0


如何在Wpf程序中使用MaterialDesign,实现mvvm,及封装常用的确认对话框、信息输入对话框、进度等待框

前言

本文通过一个简单的demo示例,介绍了MaterialDesign在wpf应用程序中的使用,实现wpf的mvvm,并封装了MaterialDesign酷炫的弹窗对话框,在此做一些总结,并在文章的最后分享完整源码。
demo效果如下:
在这里插入图片描述

搭建MaterialDesign开发环境

添加引用

在VS2022中,基于.net6.0创建wpf项目,在Nuget包管理器输入“MaterialDesign”,安装MaterialDesign。
在这里插入图片描述

添加资源字典

在App.xaml文件中添加MaterialDesign的资源字典

<Application.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml"/><ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml"/><ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.DeepPurple.xaml"/><ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml"/><!--<materialDesign:BundledTheme BaseTheme="Dark" PrimaryColor="DeepPurple" SecondaryColor="Lime"/>--></ResourceDictionary.MergedDictionaries></ResourceDictionary></Application.Resources>

编译一下,之后在MainWindow.xaml中随便加一些控件(比如Button),就能看到MaterialDesign的样式了。本demo的主界面设计如下:
在这里插入图片描述

说明:在MainWindow的设计中,使用了“<md:DialogHost Identifier=“Root”>”,其中md是对MaterialDesign的命名空间的申明,这个xaml意思是将此窗口作为对话框的DialogHost,并用“Root”命名作为唯一识别。此名称将传递到对话框中,告诉对话框悬停在哪个DialogHost上。在实际应用中,可以有多个DialogHost,取不同的名称即可。

MVVM的简单封装

在不使用第三方mvvm框架的情况下,我对INotifyPropertyChanged(绑定UI显示)和ICommand(绑定命令)进行了简单封装。如下:

ViewModelBase

internalclassViewModelBase:INotifyPropertyChanged{publiceventPropertyChangedEventHandler? PropertyChanged;protectedvoidRaisePropertyChanged([CallerMemberName]string property=null){
            PropertyChanged?.Invoke(this,newPropertyChangedEventArgs(property));}}

DelegateCommand

internalclassDelegateCommand:ICommand{publicDelegateCommand(Action<object> action){
            _action = action;}privateAction<object> _action;publiceventEventHandler? CanExecuteChanged;publicboolCanExecute(object? parameter){returntrue;}publicvoidExecute(object? parameter){
            _action?.Invoke(parameter);}}

对话框设计

一般在cs程序中最常用的对话框就是信息提示框、确认对话框、信息输入框、等待进度提示框等。这里我进行了封装,信息输入框(InputView)、信息提示/确认对话框(MessageView)、转圈等待提示框(CurcularProgressView),其中MessageView既可以做信息提示框,也可以做确认询问框。

InputView

新建一个用户控件,取名“InputView”,以此作为信息输入框。界面设计如下:
在这里插入图片描述
其中,输入框的标题、提示语、默认值,都是可以通过传入参数配置的。

MessageView

新建一个用户控件,取名“MessageView”,以此作为信息提示/确认对话框。界面设计如下:
在这里插入图片描述
其中,对话框的标题、提示语、Cancel按钮是否可见(是否询问对话框),都是可以通过传入参数配置的。

CurcularProgressView

在这里插入图片描述

对话框的参数传递及数据回传

为对话框的参数传递及数据回传,设计专门的类

internalenumCommonDialogButton{
        Cancel=0,//取消
        Ok=1//确认}/// <summary>/// 对话框返回的结果/// </summary>internalclassCommonDialogResult{/// <summary>/// 点击了哪个按钮/// </summary>publicCommonDialogButton Button {get;set;}/// <summary>/// 回传的数据/// </summary>publicobject Data {get;set;}}/// <summary>/// 对话框的参数/// </summary>publicclassCommonDialogParams{/// <summary>/// 对话框悬停的Host名称/// </summary>publicstring DialogHost {get;set;}="Root";/// <summary>/// 对话框的标题/// </summary>publicstring DialogTitle {get;set;}/// <summary>/// 对话框的提示语/// </summary>publicstring DialogTipText {get;set;}/// <summary>/// 如果是输入框,则可设置默认值/// </summary>publicstring DefaultText {get;set;}/// <summary>/// 是否是询问对话框/// </summary>publicbool IsQuestion {get;set;}}

ViewModel类(主要的功能实现类)

InputViewModel

internalclassInputViewModel:ViewModelBase{publicInputViewModel(){
            SureCommand =newDelegateCommand(Sure);
            CancelCommand =newDelegateCommand(Cancel);}privatestring title;publicstring Title
        {get{return title;}set{ title =value;RaisePropertyChanged();}}privatestring tipText;publicstring TipText
        {get{return tipText;}set{ tipText =value;RaisePropertyChanged();}}privatestring inputString;publicstring InputString
        {get{return inputString;}set{ inputString =value;RaisePropertyChanged();}}privatevoidCancel(object p){if(DialogHost.IsDialogOpen(DialogHostName))
                DialogHost.Close(DialogHostName,newCommonDialogResult(){Button=CommonDialogButton.Cancel,Data=null});}privatevoidSure(object p){if(string.IsNullOrEmpty(InputString))return;if(DialogHost.IsDialogOpen(DialogHostName)){
                DialogHost.Close(DialogHostName,newCommonDialogResult(){ Button = CommonDialogButton.Ok, Data = inputString });}}privatestring DialogHostName {get;set;}="Root";publicDelegateCommand SureCommand {get;set;}publicDelegateCommand CancelCommand {get;set;}publicvoidInitParams(CommonDialogParams p){
            DialogHostName = p.DialogHost;
            Title = p.DialogTitle;
            TipText = p.DialogTipText;
            InputString = p.DefaultText;}}

MessageViewModel

internalclassMessageViewModel:ViewModelBase{publicMessageViewModel(){
            SureCommand =newDelegateCommand(Sure);
            CancelCommand =newDelegateCommand(Cancel);}privatestring title;publicstring Title
        {get{return title;}set{ title =value;RaisePropertyChanged();}}privateVisibility visibility = Visibility.Visible;publicVisibility Visibility
        {get{return visibility;}set{ visibility =value;RaisePropertyChanged();}}privatestring content;publicstring Content
        {get{return content;}set{ content =value;RaisePropertyChanged();}}privatevoidCancel(object p){if(DialogHost.IsDialogOpen(DialogHostName))
                DialogHost.Close(DialogHostName,newCommonDialogResult(){ Button = CommonDialogButton.Cancel, Data =null});}privatevoidSure(object p){if(DialogHost.IsDialogOpen(DialogHostName)){
                DialogHost.Close(DialogHostName,newCommonDialogResult(){ Button = CommonDialogButton.Ok, Data =null});}}privatestring DialogHostName {get;set;}="Root";publicDelegateCommand SureCommand {get;set;}publicDelegateCommand CancelCommand {get;set;}publicvoidInitParams(CommonDialogParams p){
            DialogHostName = p.DialogHost;
            Title = p.DialogTitle;
            Content = p.DialogTipText;
            Visibility = p.IsQuestion ? Visibility.Visible : Visibility.Hidden;}}

调用对话框的静态方法

以下两个静态方法,分别调用信息输入框和信息提示/确认框。

internalclassCommonDialogShow{publicstaticasyncTask<object>ShowInputDialog(string host,string title,string tipText,string defaulvalue){CommonDialogParams ps =newCommonDialogParams(){ DialogHost = host, DialogTitle = title, DialogTipText = tipText, DefaultText = defaulvalue };returnawait DialogHost.Show(newInputView(ps), host);}publicstaticasyncTask<object>ShowMessageDialog(string host,string title,string tipText,bool isQuestion){CommonDialogParams ps =newCommonDialogParams(){ DialogHost = host, DialogTitle = title, DialogTipText = tipText, IsQuestion=isQuestion };returnawait DialogHost.Show(newMessageView(ps), host);}publicstaticasyncTask<object>ShowCurcularProgress(string host,Action action){
            DialogHost.Show(newCurcularProgressView(), host);try{await Task.Run(()=>{action();});returnnewCommonDialogResult(){ Button = CommonDialogButton.Ok };}finally{
                DialogHost.Close(host);}}}

MainWindow调用对话框

新建类MainWindowViewModel作为MainWindow的ViewModel,具体代码实现如下:

internalclassMainWindowViewModel:ViewModelBase{privatestring textValue="Hello, you can change this text !";publicstring TextValue
        {get{return textValue;}set{ textValue =value;RaisePropertyChanged();}}publicDelegateCommand UpdateCommand
        {get{returnnewDelegateCommand(async(src)=>{CommonDialogResult result =await CommonDialogShow.ShowInputDialog("Root","edit","please edit the text", src.ToString())asCommonDialogResult;if(result.Button == CommonDialogButton.Ok){await CommonDialogShow.ShowCurcularProgress("Root",()=>{
                            System.Threading.Thread.Sleep(2000);
                            TextValue = result.Data.ToString();});}});}}publicDelegateCommand DeleteCommand
        {get{returnnewDelegateCommand(async(src)=>{CommonDialogResult result =await CommonDialogShow.ShowMessageDialog("Root","caution","do you want to delete the text?",true)asCommonDialogResult;if(result.Button == CommonDialogButton.Ok){await CommonDialogShow.ShowCurcularProgress("Root",()=>{
                            System.Threading.Thread.Sleep(2000);
                            TextValue ="";});await CommonDialogShow.ShowMessageDialog("Root","success","the text has been deleted!",false);}});}}}

源码分享

最后,将本demo的完整源码分享在csdn上,欢迎下载共同学习和交流。
源码下载

标签: wpf ui .net

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

“如何在Wpf程序中使用MaterialDesign,实现mvvm,及封装常用的确认对话框、信息输入对话框、进度等待框”的评论:

还没有评论