WPF MVVM制作發(fā)送短信小按鈕
最近做一個(gè)項(xiàng)目,因?yàn)樯婕暗阶?cè),因此需要發(fā)送短信,一般發(fā)送短信都有一個(gè)倒計(jì)時(shí)的小按鈕,因此,就做了一個(gè),在此做個(gè)記錄。
一、發(fā)送消息
沒(méi)有調(diào)用公司的短信平臺(tái),只是模擬前臺(tái)生成一串?dāng)?shù)字,將此串?dāng)?shù)字輸出一下。
在這個(gè)部分寫(xiě)了兩個(gè)類(lèi)文件:一個(gè)是生成隨機(jī)數(shù),一個(gè)是模擬發(fā)送此數(shù)字的。
1、因?yàn)樯蓭孜浑S機(jī)數(shù),是必須要到項(xiàng)目上線之前才能定的,因此,寫(xiě)了一個(gè)帶參數(shù)的函數(shù),如下
/// <summary> /// 生成隨機(jī)驗(yàn)證碼 /// </summary> public static class RandomCode { /// <summary> /// 返回一個(gè)N位驗(yàn)證碼 /// </summary> /// <param name="N">位數(shù)</param> /// <returns></returns> public static string RandomCodeCommand(int N) { string code = ""; Random random = new Random(); for (int i = 0; i < N; i++) { code += random.Next(9); } return code; } }
2、模擬發(fā)送此串?dāng)?shù)字。
這個(gè)類(lèi)里面用了兩個(gè)Timer函數(shù),一個(gè)是用作Button的倒數(shù)顯示的,另一個(gè)是用作保存這個(gè)驗(yàn)證碼時(shí)長(zhǎng)的。
在記錄驗(yàn)證碼的同時(shí),還需要記錄發(fā)送驗(yàn)證碼的手機(jī)號(hào),以防止,用戶用第一個(gè)手機(jī)號(hào)點(diǎn)擊了發(fā)送驗(yàn)證碼后,把手機(jī)號(hào)部分修改為其他的手機(jī)號(hào)。
public class SendRandomCode : ViewModelBase { private int _interval;//記錄倒計(jì)時(shí)長(zhǎng) private string idCode;//在規(guī)定時(shí)間內(nèi)保存驗(yàn)證碼 private int idCodeTime;//設(shè)置驗(yàn)證碼的有效時(shí)間(秒) private int idCodeNum = 6;//設(shè)置驗(yàn)證碼的位數(shù) public void GetCode(string phoneNum) { //獲取驗(yàn)證碼 timerSend = new Timer(1000); timerSend.AutoReset = true; timerSend.Elapsed += Timer_Elapsed; _interval = SecondNum; timerSend.Start(); //在驗(yàn)證碼有效期內(nèi),再次請(qǐng)求驗(yàn)證碼,需要先關(guān)閉上一次的 if (timerTime != null) { timerTime.Close(); timerTime.Dispose(); } //驗(yàn)證碼的有效期 timerTime = new Timer(1000); timerTime.AutoReset = true; timerTime.Elapsed += TimerTime_Elapsed; timerTime.Start(); idCodeTime = SaveTime; IdCode = RandomCode.RandomCodeCommand(idCodeNum); PhoneNum = phoneNum; } #region 獲取驗(yàn)證碼倒計(jì)時(shí) Timer timerSend; Timer timerTime; private void Timer_Elapsed(object sender, ElapsedEventArgs e) { BtnIsEnable = false; BtnContent = "(" + (_interval--) + ")秒后再次獲取驗(yàn)證碼"; if (_interval <= -1) { BtnIsEnable = true; BtnContent = "獲取驗(yàn)證碼"; timerSend.Stop(); timerSend.Dispose(); } //throw new NotImplementedException(); } private void TimerTime_Elapsed(object sender, ElapsedEventArgs e) { idCodeTime--; if (idCodeTime <= 0) { IdCode = ""; timerTime.Stop(); timerTime.Dispose(); } Console.WriteLine(IdCode); //throw new NotImplementedException(); } #endregion #region 字段 //*************************************************************************************************//上線時(shí)需要修改 private int secondNum = 30;//設(shè)置倒計(jì)時(shí)長(zhǎng) private int saveTime = 60;//設(shè)置保存驗(yàn)證碼時(shí)長(zhǎng) //*************************************************************************************************// private string btnContent = "獲取驗(yàn)證碼";//設(shè)置獲取驗(yàn)證碼按鈕顯示的名稱(chēng) private bool btnIsEnable = true;//設(shè)置獲取驗(yàn)證碼按鈕是否可用 private string phoneNum;//記錄是否是發(fā)送驗(yàn)證碼的手機(jī)號(hào) public int SecondNum { get { return secondNum; } set { secondNum = value; } } public int SaveTime { get { return saveTime; } set { saveTime = value; } } public string BtnContent { get { return btnContent; } set { btnContent = value; RaisePropertyChanged("BtnContent"); } } public bool BtnIsEnable { get { return btnIsEnable; } set { btnIsEnable = value; RaisePropertyChanged("BtnIsEnable"); } } public string IdCode { get { return idCode; } set { idCode = value; RaisePropertyChanged("IdCode"); } } public string PhoneNum { get { return phoneNum; } set { phoneNum = value; RaisePropertyChanged("PhoneNum"); } } #endregion }
二、XAML頁(yè)面代碼
<Grid> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <StackPanel Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Horizontal"> <Label Content="手機(jī)號(hào)"/> <TextBox Text="{Binding PhoneNum}" Height="20" Width="100"/> <Button Content="{Binding Src.BtnContent}" IsEnabled="{Binding Src.BtnIsEnable}" Command="{Binding SendCode}" Height="20" Width="120"/> </StackPanel> <StackPanel Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Horizontal"> <Label Content="驗(yàn)證碼"/> <TextBox Text="{Binding IdentifyCode}" Height="20" Width="100"/> <Button Content="提交" Command="{Binding Submit}" Height="20" Width="120"/> </StackPanel> </Grid>
三、VM頁(yè)面代碼
VM頁(yè)面沒(méi)有什么特別的,就是聲明了一些字段,
特別注意的是,由于前臺(tái)的XAML頁(yè)面上的發(fā)送短信按鈕是需要倒計(jì)時(shí)的,因此Button的Content和IsEnable需要綁定到SendRandomCode這個(gè)類(lèi)上,所以需要在VM下聲明一下這個(gè)類(lèi)
public class BingVM: ViewModelBase { #region 界面字段 private string phoneNum;//手機(jī)號(hào) private string identifyCode;//驗(yàn)證碼 public string PhoneNum { get { return phoneNum; } set { phoneNum = value; RaisePropertyChanged("PhoneNum"); } } public string IdentifyCode { get { return identifyCode; } set { identifyCode = value; RaisePropertyChanged("IdentifyCode"); } } #endregion #region 為獲取驗(yàn)證碼按鈕設(shè)置content和isEnable用的 SendRandomCode src = new SendRandomCode(); public SendRandomCode Src { get { return src; } set { src = value; } } #endregion private RelayCommand sendCode;//獲取驗(yàn)證碼 public RelayCommand SendCode { get { return sendCode ?? (sendCode = new RelayCommand( () => { if (!string.IsNullOrEmpty(PhoneNum)) { src.GetCode(PhoneNum); } else { MessageBox.Show("手機(jī)號(hào)不能為空!"); } })); } } private RelayCommand submit; public RelayCommand Submit { get { return submit ?? (submit = new RelayCommand( () => { if (IdentifyCode == src.IdCode && PhoneNum == src.PhoneNum) { MessageBox.Show("驗(yàn)證成功"); } else { MessageBox.Show("驗(yàn)證失敗"); } })); } } }
四、效果展示
上面是成功的效果圖。
驗(yàn)證失敗的情況如下:
1、如果在發(fā)送驗(yàn)證碼的過(guò)程中,把手機(jī)號(hào)修改了,填入原有的驗(yàn)證碼
2、如果輸入的驗(yàn)證碼不是程序輸出的驗(yàn)證碼
3、時(shí)間超過(guò)了驗(yàn)證碼的保存時(shí)間
BUG修復(fù):
剛才在測(cè)試的過(guò)程中發(fā)現(xiàn)了一個(gè)問(wèn)題,由于我們做的主程序是調(diào)用模塊的DLL文件生成磁貼的,而主程序的返回按鈕,不會(huì)關(guān)閉掉當(dāng)前磁貼的所有線程,導(dǎo)致當(dāng)返回再進(jìn)入此磁貼時(shí),再次點(diǎn)擊發(fā)送按鈕,則會(huì)再次出現(xiàn)一個(gè)驗(yàn)證碼,解決方式很簡(jiǎn)單:修改SendRandomCode代碼,在Timer timerTime;前加static,是其成為靜態(tài)的。這樣再次點(diǎn)擊時(shí),就是知道線程已存在,先關(guān)閉再發(fā)送。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C# Onnx CenterNet實(shí)現(xiàn)目標(biāo)檢測(cè)的示例詳解
這篇文章主要為大家詳細(xì)介紹了C# Onnx CenterNet實(shí)現(xiàn)目標(biāo)檢測(cè)的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-12-12C#?webApi創(chuàng)建與發(fā)布、部署、api調(diào)用詳細(xì)教程
這篇文章主要給大家介紹了關(guān)于C#?webApi創(chuàng)建與發(fā)布、部署、api調(diào)用的相關(guān)資料,WebApi是微軟在VS2012?MVC4版本中綁定發(fā)行的,WebApi是完全基于Restful標(biāo)準(zhǔn)的框架,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12C#實(shí)現(xiàn)給Word每一頁(yè)設(shè)置不同圖片水印
Word中設(shè)置水印時(shí),可加載圖片設(shè)置為水印效果,但通常添加水印效果時(shí),會(huì)對(duì)所有頁(yè)面都設(shè)置成統(tǒng)一效果。本文將利用C#實(shí)現(xiàn)給Word每一頁(yè)設(shè)置不同圖片水印的效果,需要的可以參考一下2022-02-02C#實(shí)現(xiàn)Winform小數(shù)字鍵盤(pán)模擬器
本文主要介紹了C#實(shí)現(xiàn)Winform小數(shù)字鍵盤(pán)模擬器,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11在C#中創(chuàng)建和讀取XML文件的實(shí)現(xiàn)方法
項(xiàng)目中需要將前臺(tái)頁(yè)面中的信息保存下來(lái)并存儲(chǔ)為xml文件格式到數(shù)據(jù)庫(kù)中去。因此我先在這里通過(guò)一個(gè)小實(shí)例來(lái)學(xué)習(xí)xml的創(chuàng)建與讀取2013-09-09