WPF MVVM下做发送短信小按钮

  最近做一个项目,因为涉及到注册,因此需要发送短信,一般发送短信都有一个倒计时的小按钮,因此,就做了一个,在此做个记录。

一、发送消息

  没有调用公司的短信平台,只是模拟前台生成一串数字,将此串数字输出一下。

  在这个部分写了两个类文件:一个是生成随机数,一个是模拟发送此数字的。

  1、因为生成几位随机数,是必须要到项目上线之前才能定的,因此,写了一个带参数的函数,如下

    /// <summary>
    /// 生成随机验证码
    /// </summary>
    public static class RandomCode
    {
        /// <summary>
        /// 返回一个N位验证码
        /// </summary>
        /// <param name="N">位数</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;
        }
    }
RandomCode

  2、模拟发送此串数字。

  这个类里面用了两个Timer函数,一个是用作Button的倒数显示的,另一个是用作保存这个验证码时长的。

  在记录验证码的同时,还需要记录发送验证码的手机号,以防止,用户用第一个手机号点击了发送验证码后,把手机号部分修改为其他的手机号。

public class SendRandomCode : ViewModelBase
    {
        private int _interval;//记录倒计时长
        private string idCode;//在规定时间内保存验证码
        private int idCodeTime;//设置验证码的有效时间(秒)
        private int idCodeNum = 6;//设置验证码的位数

        public void GetCode(string phoneNum)
        {
            //获取验证码
            timerSend = new Timer(1000);
            timerSend.AutoReset = true;
            timerSend.Elapsed += Timer_Elapsed;
            _interval = SecondNum;
            timerSend.Start();

            //在验证码有效期内,再次请求验证码,需要先关闭上一次的
            if (timerTime != null)
            {
                timerTime.Close();
                timerTime.Dispose();
            }
            //验证码的有效期
            timerTime = new Timer(1000);
            timerTime.AutoReset = true;
            timerTime.Elapsed += TimerTime_Elapsed;
            timerTime.Start();
            idCodeTime = SaveTime;
            IdCode = RandomCode.RandomCodeCommand(idCodeNum);
            PhoneNum = phoneNum;
        }

        #region 获取验证码倒计时
        Timer timerSend;
        Timer timerTime;
        private void Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            BtnIsEnable = false;
            BtnContent = "(" + (_interval--) + ")秒后再次获取验证码";

            if (_interval <= -1)
            {
                BtnIsEnable = true;
                BtnContent = "获取验证码";
                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 字段
        //*************************************************************************************************//上线时需要修改
        private int secondNum = 30;//设置倒计时长
        private int saveTime = 60;//设置保存验证码时长
                                  //*************************************************************************************************//
        private string btnContent = "获取验证码";//设置获取验证码按钮显示的名称
        private bool btnIsEnable = true;//设置获取验证码按钮是否可用

        private string phoneNum;//记录是否是发送验证码的手机号
        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
    }
SendRandomCode

二、XAML页面代码 

<Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Horizontal">
            <Label Content="手机号"/>
            <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="验证码"/>
            <TextBox Text="{Binding IdentifyCode}" Height="20" Width="100"/>
            <Button Content="提交" Command="{Binding Submit}" Height="20" Width="120"/>
        </StackPanel>
    </Grid>
XAML

三、VM页面代码  

  VM页面没有什么特别的,就是声明了一些字段,

  特别注意的是,由于前台的XAML页面上的发送短信按钮是需要倒计时的,因此Button的Content和IsEnable需要绑定到SendRandomCode这个类上,所以需要在VM下声明一下这个类

public class BingVM: ViewModelBase
    {
        #region 界面字段
        private string phoneNum;//手机号
        private string identifyCode;//验证码
        public string PhoneNum
        {
            get
            {
                return phoneNum;
            }

            set
            {
                phoneNum = value;
                RaisePropertyChanged("PhoneNum");
            }
        }

        public string IdentifyCode
        {
            get
            {
                return identifyCode;
            }

            set
            {
                identifyCode = value;
                RaisePropertyChanged("IdentifyCode");
            }
        }
        #endregion

        #region 为获取验证码按钮设置content和isEnable用的
        SendRandomCode src = new SendRandomCode();
        public SendRandomCode Src
        {
            get { return src; }
            set
            {
                src = value;
            }
        }
        #endregion

        private RelayCommand sendCode;//获取验证码

        public RelayCommand SendCode
        {
            get
            {
                return sendCode ?? (sendCode = new RelayCommand(
                    () =>
                    {
                        if (!string.IsNullOrEmpty(PhoneNum))
                        {
                            src.GetCode(PhoneNum);
                        }
                        else
                        {
                            MessageBox.Show("手机号不能为空!");
                        }

                    }));
            }
        }
        private RelayCommand submit;

        public RelayCommand Submit
        {
            get
            {
                return submit ?? (submit = new RelayCommand(
                    () =>
                    {
                        if (IdentifyCode == src.IdCode && PhoneNum == src.PhoneNum)
                        {
                            MessageBox.Show("验证成功");
                        }
                        else
                        {
                            MessageBox.Show("验证失败");
                        }
                    }));
            }
        }

    }
VM

四、效果展示

 

 

 

 

 

 

 

 

 

 

上面是成功的效果图

验证失败的情况如下:

1、如果在发送验证码的过程中,把手机号修改了,填入原有的验证码

2、如果输入的验证码不是程序输出的验证码

3、时间超过了验证码的保存时间

=============================================================================

BUG修复:

刚才在测试的过程中发现了一个问题,由于我们做的主程序是调用模块的DLL文件生成磁贴的,而主程序的返回按钮,不会关闭掉当前磁贴的所有线程,导致当返回再进入此磁贴时,再次点击发送按钮,则会再次出现一个验证码,解决方式很简单:修改SendRandomCode代码,在Timer timerTime;前加static,是其成为静态的。这样再次点击时,就是知道线程已存在,先关闭再发送。

原文地址:https://www.cnblogs.com/ZXdeveloper/p/4831672.html