0


【WPF】消息蒙版弹窗UI以及await实现等待反馈(popup)

文章目录

一、概要

原版的消息框太丑?不喜欢?如果您对原版消息框的外观不太满意,或者不符合您的应用程序的需求,那么可以通过自定义消息框来实现所需的外观和功能。

原版的消息框:
原版消息框展示

可以看出这个消息框可能和你设计的UI界面格格不入

自定义消息框可以实现各种风格和布局的效果。
下面我展示一个B端设计的消息框界面
设计来自B端-薪福通
那么我们如何做到类似的效果呢?

  • 构思背景遮罩逻辑
  • 制作UI界面(遮罩+Popup)
  • Cs后端弹窗实现(Await)

实现效果展示:
退出实现效果展示
演示GIF

其中,按钮颜色、文本,图标等都可以通过自定义。

二、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="&#xe743;"FontFamily="{DynamicResource Iconfont}"FontSize="22"VerticalAlignment="Center"Margin="10"/><TextBlockx:Name="MessageIconC"Text="&#xe623;"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="&#xe620;"/></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是删除按钮哦,可以看前面的定义

四、技术细节/常见错误

  1. 消息框初始化需要关闭状态。不然会出错哦
  2. Popup的StaysOpen="True",不然点击其他地方就自动关闭了,然后就会剩下遮罩无法操作
  3. Popup和Grid都需要在用户操作完后隐藏!
  4. 在调用需要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="&#xe743;"FontFamily="{DynamicResource Iconfont}"FontSize="22"VerticalAlignment="Center"Margin="10"/><TextBlockx:Name="MessageIconC"Text="&#xe623;"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="&#xe620;"/></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("-你点击了取消-","提示:");}}}}

感谢观看,代码还有需要完善的地方,欢迎指正。
源码因为某些原因不能放出,有需要可以私信我。

标签: wpf ui c#

本文转载自: https://blog.csdn.net/XcommandStudio/article/details/133492485
版权归原作者 XcommandStudio 所有, 如有侵权,请联系我们删除。

“【WPF】消息蒙版弹窗UI以及await实现等待反馈(popup)”的评论:

还没有评论