前言:
当你F5运行时,在弹出对话框之后,如果你不即时点确定,或者上个WC回来之后,你会发现已经提示出错了
这节开始,我们将对其进行一小步一小步的优化,来避免一些明显容易引发的错误。
感知一下最原始的消息弹出框如下图:
一:传统消息框,容易引发命案
1:原始的消息框,是线程阻塞类型的,很容易引发超时问题
线程阻塞?怎么理解?
会产生什么问题?
解决方案?
a:传统解决方案[加上倒计时,还是线程阻塞类型]
于是搜了一些资料,发现要用winapi来处理,这个这个....大才小用了吧。
b:更优的解决方案
因为 ChildWindow使用异步方式,非线程阻塞,消息一弹之后线程就回家去了。
而且用Sivlerlight内置的定时器DispatcherTimer,非常容易实现倒计时。
二:实现自定义非线程阻塞倒计时对话框,纯种Sivlerlight
1:看看纯种的长成什么样
比如在登陆页面测试一下:MsgBox box=new MsgBox();box.Show();
结果所见如图:
说明:
2:重点提示:当初刚试的时候是直接运行MsgBox,然后在其构造函数中调用Show(),结果是出不来的。
2:改造-界面小小改动
我们将原来的xaml改造成如下:

< Grid x:Name ="LayoutRoot" Margin ="2" Height ="97" Width ="270" >
< Button Visibility ="Collapsed" x:Name ="CancelButton" Content ="取消" Click ="CancelButton_Click" Width ="75" Height ="23" HorizontalAlignment ="Right" Margin ="0,62,93,12" />
< Button x:Name ="OKButton" Content ="确定" Click ="OKButton_Click" Width ="75" Height ="23" HorizontalAlignment ="Right" Margin ="0,62,10,12" />
< TextBlock Height ="41" TextWrapping ="Wrap" HorizontalAlignment ="Left" Margin ="15,15,0,0" Name ="tbMsg" Text ="请按确定按钮确定" VerticalAlignment ="Top" Width ="224" />
</ Grid >
</ controls:ChildWindow >
界面效果如图,和上图差不多[这里把取消放在前面,只是为了不显示取消时,确定还保留在原位好看点]:
3:改造,在标题加入倒计时
a:加入计时器并初始化

public MsgBox()
{
InitializeComponent();
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds( 1 );
timer.Tick += new EventHandler(timer_Tick);
}
b:新加show方法并实现倒计时

string userTitle;
DispatcherTimer timer; // 定时器
public MsgBox()
{
// ...省略...
}
void timer_Tick( object sender, EventArgs e)
{
Title = string .Format(userTitle + " [倒计时自动确定:{0}秒] " , defaultTime);
defaultTime -- ;
if (defaultTime == 0 )
{
ResetTimer();
}
}
void ResetTimer()
{
timer.Stop();
defaultTime = 3 ;
}
public void Show( string msg, string title)
{
tbMsg.Text = msg;
userTitle = title;
Show();
timer.Start();
}
c:再调用一下看结果
box.Show( " http://cyq1162.cnblogs.com " , " 路过秋天 " );
如图:
4:扩展show函数:加入回调/倒计时时间/按钮类型/默认确认类型
接着:默认3秒,很明显情况不同,时间也要稍为增加变动一下;
然后:有时候按钮只是确定,有时候就是取消+确定;
于是,要实现了:
a:如何实现回调?
默认子窗口就有Closed事件,我们用它的事件,在点击确定或取消时,执行Close()方法

{
InitializeComponent();
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds( 1 );
timer.Tick += new EventHandler(timer_Tick);
this .Closed += new EventHandler(MsgBox_Closed);
}
void MsgBox_Closed( object sender, EventArgs e)
{
// 待实现
}
private void OKButton_Click( object sender, RoutedEventArgs e)
{
this .DialogResult = true ;
Close(); // 调用一下关闭
}
private void CancelButton_Click( object sender, RoutedEventArgs e)
{
this .DialogResult = false ;
Close(); // 调用一下关闭
}
问题?我们难道对所有的确定都执行相同的代码?
于是说:这是个很严重的问题,因为不同的确定,我们执行的事件肯定是不同的。
解决问题?匿名委托出手了!!!
匿名委托实现:
void MsgBox_Closed( object sender, EventArgs e)
{
if (callBackEvent != null )
{
callBackEvent(DialogResult.Value);
}
}
那委托是如何传入的?Show方法增加扩展参数传入。
b:这里贴出完整代码,一并实现:倒计时时间/按钮类型/默认确认类型

三:接下来便是苦力活了,把原来用到传统对框的提示,通通改过来。
最后上一实际应用中的图:
版权声明:本文原创发表于博客园,作者为路过秋天,原文链接:
http://www.cnblogs.com/cyq1162/archive/2010/10/27/1861281.html