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; } }
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 }
二、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>
三、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("验证失败"); } })); } } }
四、效果展示
上面是成功的效果图。
验证失败的情况如下:
1、如果在发送验证码的过程中,把手机号修改了,填入原有的验证码
2、如果输入的验证码不是程序输出的验证码
3、时间超过了验证码的保存时间
bug修复:
刚才在测试的过程中发现了一个问题,由于我们做的主程序是调用模块的dll文件生成磁贴的,而主程序的返回按钮,不会关闭掉当前磁贴的所有线程,导致当返回再进入此磁贴时,再次点击发送按钮,则会再次出现一个验证码,解决方式很简单:修改sendrandomcode代码,在timer timertime;前加static,是其成为静态的。这样再次点击时,就是知道线程已存在,先关闭再发送。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。