最近做一个项目,因为涉及到注册,因此需要发送短信,一般发送短信都有一个倒计时的小按钮,因此,就做了一个,在此做个记录。
一、发送消息
没有调用公司的短信平台,只是模拟前台生成一串数字,将此串数字输出一下。
在这个部分写了两个类文件:一个是生成随机数,一个是模拟发送此数字的。
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,是其成为静态的。这样再次点击时,就是知道线程已存在,先关闭再发送。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:http://www.cnblogs.com/ZXdeveloper/p/4831672.html
dy("nrwz");
查看更多关于WPF MVVM制作发送短信小按钮的详细内容...