
The Curious Incident of the MessageBox in the Silverlight App
在线演示如下: [url]http://silverlight.services.live.com/invoke/72193/messagebox/iframe.html[/url]
首先是普通样式:
接着是显示图形样式:
使用新的样式风格:
首先请下载本文中的源码(本人已部分修改了原文中的源码和相应的样式,以便进行DEMO演示)。下面是相应的类图和说明:
接下来,将会以这个类图来逐个解释相应类结构信息,首先看一下MessageBoxControls(相应内容见注释):
Code
/// <summary>
消息框结果
</summary>
public enum MessageBoxResult
{
Yes, //是
No, 否 Cancel 取消}
消息事件参数
class MessageBoxResultEventArgs : EventArgs
{
MessageBoxResult Result { get; set; }
object AsyncState { ; }
}
消息框控件类,该模板包括三个组件(三个button和一个Panel)
[TemplatePart(name = RootElement, Type typeof(Panel))]
[TemplatePart(name YesbuttonElement,0);">(button))]
[TemplatePart(name NobuttonElement,0);"> ((button)))]
[TemplatePart(name CancelbuttonElement,0);">(button)))]
MessageBoxControl : ContentControl
{
event EventHandler<MessageBoxResultEventArgs> MessageBoxdismissed;
MessageBoxControl()
{
DefaultStyleKey (MessageBoxControl);
}
overrIDevoID OnApplyTemplate()
{
#region 取消之前的事件绑定
if (yesbutton !=null)
{
yesbutton.Click -= OnYesbutton;
}
(nobutton )
{
nobutton.Click OnNobutton;
}
(cancelbutton )
{
cancelbutton.Click OnCancelbutton;
}
#endregion
rootElement base.GetTemplateChild(RootElement) as Panel;
yesbutton .GetTemplateChild(YesbuttonElement) button;
nobutton .GetTemplateChild(NobuttonElement) button;
cancelbutton .GetTemplateChild(CancelbuttonElement) button;
如果grID中有相应元素时,则绑定相应事件(详见下面的代码)+=
}
OnYesbutton( sender, EventArgs args)
{
Firedismissed(MessageBoxResult.Yes);
}
OnNobutton( OnCancelbutton(
调用绑定的事件,并传递相应参数
</summary><param name="result"></param> Firedismissed(MessageBoxResult result)
{
当绑定的事件不为空时(绑定部分参见MessageBox的构造函数) (MessageBoxdismissed )
{
MessageBoxdismissed(this, new MessageBoxResultEventArgs() { Result result });
}
}
button yesbutton;
button nobutton;
button cancelbutton;
Panel rootElement;
赋值信息参见generic.xaml中的"x:name"声明
conststring RootElement "RootElement";
YesbuttonElement YesbuttonElement NobuttonElement NobuttonElement CancelbuttonElement CancelbuttonElement;
}
而MessageBox这个控件使用封装类结构如下(相关内容见注释):
Code
UserControlContentAccessor : UserControl
{
获取当前UserControl的contentproperty属性
<param name="uc">当前UserControl</param><returns>contentproperty属性</returns>static UIElement GetContent(UserControl uc)
{
return ((UIElement)uc.GetValue(UserControl.contentproperty));
}
设置当前UserControl的contentproperty属性
<param name="element">要设置的内容属性</param> SetContent(UserControl uc, UIElement element)
{
uc.SetValue(UserControl.contentproperty, element);
}
}
消息框类,该类可以看成是对"消息框控件类"使用封装(封装了事件绑定和内容信息)
MessageBox
{
实际页面视图中的元素(用于当消息框关闭后,还原页面元素时使用)
private UIElement realVisual;
用于绑定当前页面中根元素节点
GrID parentGrID;
状态值
asyncState;
用户绑定回调事件属性
userCallback;
ShowAsync( content)
{
ShowAsync(content,0);">);
}
content,
EventHandler callback)
{
ShowAsync(content, callback);
}
userState, userState, callback,0);"> callback, Style controlTemplate)
{
MessageBoxControl control MessageBoxControl();
control.Content content;
绑定指定样式 (controlTemplate )
{
control.Style controlTemplate;
}
ShowAsync(control, callback);
}
ShowAsync(MessageBoxControl control,0);"> callback)
{
UserControl uc Application.Current.RootVisual UserControl;
(uc )
{
asyncState userState;用户状态绑定 userCallback callback;回调方法 realVisual UserControlContentAccessor.GetContent(uc);
realVisual.IsHitTestVisible false; 使底层控件点击不可见
parentGrID GrID();声明一个GrID对象,用于加载新的内容 UserControlContentAccessor.SetContent(uc, parentGrID);
parentGrID.Children.Add(realVisual); 加载realVisual内容(注:此处内容中的控制已不支持点击了) parentGrID.Children.Add(control); 加载消息框实例,后加载的显示在上(前)面
control.MessageBoxdismissed Ondismissed; 绑定要处理的事件,该事件会在点击消息框中的"yes"或"no"按钮时执行 }
}
Ondismissed( sender MessageBoxControl;
UserControl uc )
{ 清除之前的页面UI元素,并还原页面初始时的元素设置 parentGrID.Children.Clear();
realVisual.IsHitTestVisible true;
UserControlContentAccessor.SetContent(uc, realVisual);
}
(control )
{
control.MessageBoxdismissed Ondismissed;
}
try
{
(userCallback )
{
执行用户绑定的事件(并传递事件参数) userCallback( MessageBoxResultEventArgs()
{
Result e.Result,
AsyncState asyncState
});
}
}
finally
{
realVisual ;
parentGrID ;
asyncState ;
userCallback ;
}
}
}
其实通过上面的类,我们可以看出作者是如何在当前页面中显示消息框信息的,也就是上面代码段里
的如下代码:
realVisual = UserControlContentAccessor.GetContent(uc);
realVisual.IsHitTestVisible false ; // 使底层控件点击不可见
parentGrID new GrID(); 声明一个GrID对象,用于加载新的内容 UserControlContentAccessor.SetContent(uc, parentGrID);
parentGrID.Children.Add(realVisual); 加载realVisual内容(注:此处内容中的控制已不支持点击了) parentGrID.Children.Add(control);
也就是通过realVisual来保存原有的页面元素信息,然后重新按指定顺序(先realVisual再messagecontrol)加载UIElement来实现显示消息框的方式,当然这种有Hack味道的做法到底效果好不好,连原作者都表示怀疑,他
本人也感觉还应有更好的Solution。
当然realVisual变量的一个重要用处在于当消息框被关闭时,用它来还原页面中的元素,而这块代码就是上面所说的Ondismissed方法所做的事了,代码如下:
Ondismissed ( object sender as MessageBoxControl;
UserControl uc Application.Current.RootVisual UserControl;
if (uc != null )
{ 清除之前的页面UI元素,并还原页面初始时的元素设置 parentGrID.Children.Clear();
realVisual.IsHitTestVisible true ;
UserControlContentAccessor.SetContent(uc, realVisual);
}
}
这样,我们可以在应用程序中使用该类来显示相应的消息框了,其声明和使用代码如下:
普通样式 voID OnnormalClick( " 简单调用, 无回调, 无状态, 无样式! " );
下面注释的代码包括状态和回调事件
MessageBox.ShowAsync("As prevIoUsly but with a callback - hit NO", (s, e) =>
{
DeBUG.Assert(e.Result == MessageBoxResult.No);
});
MessageBox.ShowAsync("As prevIoUsly but with state - hit YES", 101,0);"> DeBUG.Assert((e.Result == MessageBoxResult.Yes) && ((int)e.AsyncState == 101));
}); }
显示图形 OnShapeClick( Ellipse()
{
WIDth 80 Fill SolIDcolorBrush(colors.Green)
});
}
转换样式 OnChangeStyleClick( this .Resources[ myStyle ] Style;
MessageBox.ShowAsync( 使用一个不同的样式 101 状态 (s, e) => 处理事件 {
(e.Result == MessageBoxResult.No && (( int )e.AsyncState ))
{
HTMLPage.Window.Alert( 您点击了No按钮 );
}
MessageBoxResult.Yes)
{
HTMLPage.Window.Alert( 您点击了Yes按钮 );
}
},
myStyle);
}
说到这里,还有一个内容没有介绍,也就是作者所定义的两个样式文件,其中之一被放置到了generic.xaml中,以便做了控制默认加载样式,其绑定直接在MessageBoxControl构造函数中完成,如下:
public MessageBoxControl()
{
DefaultStyleKey typeof (MessageBoxControl);
}
而另外的样式被放在了page.xaml中,以便于程序运行时访问,这里就不多作介绍了。不过本人已修改了这两个样式中的一些数值,主要是为了显示时比例更好看一些。
好了,今天的内容就先到这里了。
tag : silverlight,messagexBox
作者: 代震军,daizhj
原帖链接: [url]http://files.cnblogs.com/daizhj/silverlight_MessageBox.rar[/url] 总结
以上是内存溢出为你收集整理的在silverlight中定制自己的MessageBox(消息框)全部内容,希望文章能够帮你解决在silverlight中定制自己的MessageBox(消息框)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)