文章目录
一、概要
原版的消息框太丑?不喜欢?如果您对原版消息框的外观不太满意,或者不符合您的应用程序的需求,那么可以通过自定义消息框来实现所需的外观和功能。
原版的消息框:
可以看出这个消息框可能和你设计的UI界面格格不入
自定义消息框可以实现各种风格和布局的效果。
下面我展示一个B端设计的消息框界面
那么我们如何做到类似的效果呢?
- 构思背景遮罩逻辑
- 制作UI界面(遮罩+Popup)
- Cs后端弹窗实现(Await)
实现效果展示:
其中,按钮颜色、文本,图标等都可以通过自定义。
二、UI制作流程
下面我们一步一步制作这个弹窗。
1.遮罩逻辑
首先是背景层:
背景层是一个半透明的遮罩蒙版。
<Gridx:Name="MessageGridBox"Visibility="Collapsed"><BorderBackground="White"Opacity="0.8"CornerRadius="5"/><!--这里放消息框的部分--!/><!--这里放消息框的部分--!/></Grid>
效果就是一块蒙版挡住用户其他使用区域。(当然你也可以选择不挡着或者设计逻辑选择性挡住或者不挡住,挡住的话可以防止用户不处理这个消息就去其他操作。)
这里的CornerRadius="5"
可以改为自己的主界面的圆角,当然也可以不设置。
2.Popup展示层
中间层是Popup展示层:
为了让消息框弹出不那么突兀,使用了
Popup
的
Fade
展示效果显示。
<Popupx:Name="MessageGridPopup"PopupAnimation="Fade"Placement="Center"AllowsTransparency="True"StaysOpen="True"><GridHorizontalAlignment="Center"VerticalAlignment="Center"MaxWidth="450"MaxHeight="250"MinWidth="400"MinHeight="165"><Grid.RowDefinitions><RowDefinitionHeight="55"/><RowDefinition/></Grid.RowDefinitions><RectangleGrid.RowSpan="2"Fill="White"Margin="5"Opacity="1"RadiusY="5"RadiusX="5"><Rectangle.Effect><DropShadowEffectColor="#FFBBBBBB"Direction="0"BlurRadius="10"RenderingBias="Quality"ShadowDepth="0"Opacity="0.3"></DropShadowEffect></Rectangle.Effect></Rectangle><!--这里放消息展示内容部分--!/><!--这里放消息展示内容部分--!/></Grid></Popup>
3.消息展示层
消息展示层是核心区域,用于动态更新消息框的展示文本。
我分三个部分来介绍:
- 标题部分
<GridMargin="10,0,10,0"><StackPanelOrientation="Horizontal"VerticalAlignment="Bottom"Margin="10,0,0,0"><TextBlockx:Name="MessageIconQ"Text=""FontFamily="{DynamicResource Iconfont}"FontSize="22"VerticalAlignment="Center"Margin="10"/><TextBlockx:Name="MessageIconC"Text=""FontFamily="{DynamicResource Iconfont}"FontSize="22"VerticalAlignment="Center"Margin="10"Visibility="Collapsed"/><TextBlockx:Name="MessageTitleBox"Text="标题显示"FontFamily="{DynamicResource BlodFont}"FontSize="15"VerticalAlignment="Center"/></StackPanel><ButtonHorizontalAlignment="Right"VerticalAlignment="Bottom"Margin="0,0,20,10"FontSize="22"Style="{DynamicResource wdButton}"Click="CancelBtn_Click"><Button.Content><TextBlockFontFamily="{DynamicResource Iconfont}"Text=""/></Button.Content></Button></Grid>
- 内容区域
<StackPanelGrid.RowSpan="2"Margin="10"><TextBlockx:Name="MessageContentBox"Margin="50,60,50,80"TextWrapping="Wrap"Text="消息框测试"FontSize="14"FontFamily="{DynamicResource RegularFont}"/></StackPanel>
- 按钮部分
<StackPanelGrid.Row="1"Orientation="Horizontal"VerticalAlignment="Bottom"HorizontalAlignment="Right"Margin="10"><Buttonx:Name="CancelBtn"Content="取消"Style="{DynamicResource wButton}"Width="100"FontSize="15"Height="35"Margin="10"Click="CancelBtn_Click"/><Buttonx:Name="ConfirmBtn"Content="确定"Style="{DynamicResource mButton}"Width="100"FontSize="15"Height="35"Margin="10"Click="ConfirmBtn_Click"/></StackPanel>
按钮还可以继续增加,逻辑我就不赘述了,可以看后面的代码研究一下。
值得注意的是:这里的
Style
是我自己做的,你也可以更换为自己的按钮样式,如果有需要可以后台私信我。除了底层逻辑,这些样式都可以自己自定义。
三、C#后端代码逻辑
1. 定义变量
首先定义一个
TaskCompletionSource<bool>
命名
taskCompletionSource
,当然名字可以自己改。
privateTaskCompletionSource<bool> taskCompletionSource;#这段内容需要全局变量哦
2. 定义函数
写一个显示消息框的函数,注意函数需要
async
才支持等待用户回复。
privateasyncTask<bool>ShowMessageGridBoxAsync(string MessageContent,string title,bool isconfirm =true,int ButtonIndex=0){/// <summary>/// 参数分别是 /// MessageContent 信息内容/// title 信息标题/// isconfirm 是否确认按钮(判断Icon情况)/// ButtonIndex 按钮类型/// </summary> //#我这里的后两个参数带默认值,所以可以直接简化写。//#展示消息框
MessageGridBox.Visibility = Visibility.Visible;
MessageTitleBox.Text = title;
MessageContentBox.Text = MessageContent;//#上面这些比较简单就不赘述了。分别赋值进去。//#重新赋值一个 taskCompletionSource 让其重置。
taskCompletionSource =newTaskCompletionSource<bool>();//#判断ICON 其中MessageIconC是确认的ICON,MessageIconQ是询问的ICONif(isconfirm){
CancelBtn.Visibility = Visibility.Collapsed;
MessageIconC.Visibility = Visibility.Visible;
MessageIconQ.Visibility = Visibility.Collapsed;}else{
CancelBtn.Visibility = Visibility.Visible;
MessageIconC.Visibility = Visibility.Collapsed;
MessageIconQ.Visibility = Visibility.Visible;}//#判断按钮的类型switch(ButtonIndex){case0:
ConfirmBtn.SetValue(Button.StyleProperty, Application.Current.Resources["mButton"]);
ConfirmBtn.Content ="确认";break;case1:
ConfirmBtn.SetValue(Button.StyleProperty, Application.Current.Resources["RButton"]);
ConfirmBtn.Content ="删除";
System.Media.SystemSounds.Exclamation.Play();break;case2:
ConfirmBtn.SetValue(Button.StyleProperty, Application.Current.Resources["RButton"]);
ConfirmBtn.Content ="确认";
System.Media.SystemSounds.Exclamation.Play();break;case3:
ConfirmBtn.SetValue(Button.StyleProperty, Application.Current.Resources["RButton"]);
ConfirmBtn.Content ="重试";
System.Media.SystemSounds.Exclamation.Play();break;case4:
ConfirmBtn.SetValue(Button.StyleProperty, Application.Current.Resources["mButton"]);
ConfirmBtn.Content ="我知道了";break;}//#这里写了4个类型,你可以再自定义更多//#这里要先关闭再打开!不然动态效果就没了。
MessageGridPopup.IsOpen =false;
MessageGridPopup.IsOpen =true;//#等待Task用户操作await taskCompletionSource.Task;//#操作后隐藏遮罩与Popup
MessageGridBox.Visibility = Visibility.Collapsed;
MessageGridPopup.IsOpen =false;//#返回Task的Resultreturn taskCompletionSource.Task.Result;}
3.写按钮按下的逻辑
privatevoidConfirmBtn_Click(object sender,RoutedEventArgs e){// 设置任务结果为true,并标记任务为已完成
taskCompletionSource.SetResult(true);}privatevoidCancelBtn_Click(object sender,RoutedEventArgs e){// 设置任务结果为false,并标记任务为已完成
taskCompletionSource.SetResult(false);}
4.如何调用这个函数
确认框情况
ShowMessageGridBoxAsync("-欢迎使用-","欢迎:");
需要判断的情况
bool result =awaitShowMessageGridBoxAsync("寻找不到该文件,是否删除?","错误:",false,1);//这里的1是删除按钮哦,可以看前面的定义
四、技术细节/常见错误
- 消息框初始化需要关闭状态。不然会出错哦
- Popup的
StaysOpen="True"
,不然点击其他地方就自动关闭了,然后就会剩下遮罩无法操作 - Popup和Grid都需要在用户操作完后隐藏!
- 在调用需要await的情况,所在函数需要支持
async
才可以,“await”运算符只能用于异步方法中。请考虑用“async"修饰符标记此方法。
举个例子:
privateasyncvoidDeleteButton_Click(object sender,RoutedEventArgs e){bool result =awaitShowMessageGridBoxAsync("点击删除后记录将被删除,该操作不可逆。","确认要删除这条记录么?",false,1);if(result){//按钮逻辑}}
五、小结/完整代码
Xml部分
<Gridx:Name="MessageGridBox"Visibility="Collapsed"><BorderBackground="White"Opacity="0.8"CornerRadius="5"/><Popupx:Name="MessageGridPopup"PopupAnimation="Fade"Placement="Center"AllowsTransparency="True"StaysOpen="True"><GridHorizontalAlignment="Center"VerticalAlignment="Center"MaxWidth="450"MaxHeight="250"MinWidth="400"MinHeight="165"><Grid.RowDefinitions><RowDefinitionHeight="55"/><RowDefinition/></Grid.RowDefinitions><RectangleGrid.RowSpan="2"Fill="White"Margin="5"Opacity="1"RadiusY="5"RadiusX="5"><Rectangle.Effect><DropShadowEffectColor="#FFBBBBBB"Direction="0"BlurRadius="10"RenderingBias="Quality"ShadowDepth="0"Opacity="0.3"></DropShadowEffect></Rectangle.Effect></Rectangle><GridMargin="10,0,10,0"><StackPanelOrientation="Horizontal"VerticalAlignment="Bottom"Margin="10,0,0,0"><TextBlockx:Name="MessageIconQ"Text=""FontFamily="{DynamicResource Iconfont}"FontSize="22"VerticalAlignment="Center"Margin="10"/><TextBlockx:Name="MessageIconC"Text=""FontFamily="{DynamicResource Iconfont}"FontSize="22"VerticalAlignment="Center"Margin="10"Visibility="Collapsed"/><TextBlockx:Name="MessageTitleBox"d:Text="标题显示"FontFamily="{DynamicResource BlodFont}"FontSize="15"VerticalAlignment="Center"/></StackPanel><ButtonHorizontalAlignment="Right"VerticalAlignment="Bottom"Margin="0,0,20,10"FontSize="22"Style="{DynamicResource wdButton}"Click="CancelBtn_Click"><Button.Content><TextBlockFontFamily="{DynamicResource Iconfont}"Text=""/></Button.Content></Button></Grid><StackPanelGrid.RowSpan="2"Margin="10"><TextBlockx:Name="MessageContentBox"Margin="50,60,50,80"TextWrapping="Wrap"Text="消息框测试"FontSize="14"FontFamily="{DynamicResource RegularFont}"/></StackPanel><StackPanelGrid.Row="1"Orientation="Horizontal"VerticalAlignment="Bottom"HorizontalAlignment="Right"Margin="10"><Buttonx:Name="CancelBtn"Content="取消"Style="{DynamicResource wButton}"Width="100"FontSize="15"Height="35"Margin="10"Click="CancelBtn_Click"/><Buttonx:Name="ConfirmBtn"Content="确定"Style="{DynamicResource mButton}"Width="100"FontSize="15"Height="35"Margin="10"Click="ConfirmBtn_Click"/></StackPanel></Grid></Popup></Grid>
C#部分
namespacePro{publicpartialclassMainWindow:Window{privateTaskCompletionSource<bool> taskCompletionSource;/// <summary>/// 参数分别是 /// MessageContent 信息内容/// title 信息标题/// isconfirm 是否确认按钮(判断Icon情况)/// ButtonIndex 按钮类型/// </summary> privateasyncTask<bool>ShowMessageGridBoxAsync(string MessageContent,string title,bool isconfirm =false,int ButtonIndex=0){//#我这里的后两个参数带默认值,所以可以直接简化写。//#展示消息框
MessageGridBox.Visibility = Visibility.Visible;
MessageTitleBox.Text = title;
MessageContentBox.Text = MessageContent;//#上面这些比较简单就不赘述了。分别赋值进去。//#重新赋值一个 taskCompletionSource 让其重置。
taskCompletionSource =newTaskCompletionSource<bool>();//#判断ICON 其中MessageIconC是确认的ICON,MessageIconQ是询问的ICONif(isconfirm){
CancelBtn.Visibility = Visibility.Collapsed;
MessageIconC.Visibility = Visibility.Visible;
MessageIconQ.Visibility = Visibility.Collapsed;}else{
CancelBtn.Visibility = Visibility.Visible;
MessageIconC.Visibility = Visibility.Collapsed;
MessageIconQ.Visibility = Visibility.Visible;}//#判断按钮的类型switch(ButtonIndex){case0:
ConfirmBtn.SetValue(Button.StyleProperty, Application.Current.Resources["mButton"]);
ConfirmBtn.Content ="确认";break;case1:
ConfirmBtn.SetValue(Button.StyleProperty, Application.Current.Resources["RButton"]);
ConfirmBtn.Content ="删除";
System.Media.SystemSounds.Exclamation.Play();break;case2:
ConfirmBtn.SetValue(Button.StyleProperty, Application.Current.Resources["RButton"]);
ConfirmBtn.Content ="确认";
System.Media.SystemSounds.Exclamation.Play();break;case3:
ConfirmBtn.SetValue(Button.StyleProperty, Application.Current.Resources["RButton"]);
ConfirmBtn.Content ="重试";
System.Media.SystemSounds.Exclamation.Play();break;case4:
ConfirmBtn.SetValue(Button.StyleProperty, Application.Current.Resources["mButton"]);
ConfirmBtn.Content ="我知道了";break;}//#这里写了4个类型,你可以再自定义更多//#这里要先关闭再打开!不然动态效果就没了。
MessageGridPopup.IsOpen =false;
MessageGridPopup.IsOpen =true;//#等待Task用户操作await taskCompletionSource.Task;//#操作后隐藏遮罩与Popup
MessageGridBox.Visibility = Visibility.Collapsed;
MessageGridPopup.IsOpen =false;//#返回Task的Resultreturn taskCompletionSource.Task.Result;}privatevoidConfirmBtn_Click(object sender,RoutedEventArgs e){// 设置任务结果为true,并标记任务为已完成
taskCompletionSource.SetResult(true);}privatevoidCancelBtn_Click(object sender,RoutedEventArgs e){// 设置任务结果为false,并标记任务为已完成
taskCompletionSource.SetResult(false);}privateasyncvoidDeleteButton_Click(object sender,RoutedEventArgs e){bool result =awaitShowMessageGridBoxAsync("点击删除后记录将被删除,该操作不可逆。","确认要删除这条记录么?",false,1);if(result){ShowMessageGridBoxAsync("-你点击了删除-","提示:");}else{ShowMessageGridBoxAsync("-你点击了取消-","提示:");}}}}
感谢观看,代码还有需要完善的地方,欢迎指正。
源码因为某些原因不能放出,有需要可以私信我。
版权归原作者 XcommandStudio 所有, 如有侵权,请联系我们删除。