.NET Core 3 WPF MVVM框架 Prism系列之对话框服务

简介:

.NET Core 3 WPF MVVM框架 Prism系列之对话框服务

本文将介绍如何在.NET Core3环境下使用MVVM框架Prism的对话框服务,这也是prism系列的最后一篇完结文章,下面是Prism系列文章的索引:
.NET Core 3 WPF MVVM框架 Prism系列之文章索引

一.对话框服务#
在Prism中,通过一个IDialogAware接口来实现对话框服务:

Copy
public interface IDialogAware
{

bool CanCloseDialog();
void OnDialogClosed();
void OnDialogOpened(IDialogParameters parameters);
string Title { get; set; }
event Action<IDialogResult> RequestClose;

}
CanCloseDialog()函数是决定窗体是否关闭
OnDialogClosed()函数是窗体关闭时触发,触发条件取决于CanCloseDialog()函数
OnDialogOpened()函数时窗体打开时触发,比窗体Loaded事件早触发
Title为窗体的标题
RequestClose为关闭事件,可由此控制窗体的关闭
1.创建对话框的View和ViewModel#
AlertDialog.xaml:

Copy

         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:PrismMetroSample.Shell.Views.Dialogs"
         mc:Ignorable="d"  
         xmlns:prism="http://prismlibrary.com/"
         Width="350" Height="120" prism:ViewModelLocator.AutoWireViewModel="True">
<Grid  Margin="5">
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <Grid Margin="0,0,0,10">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="70"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Image Source="pack://application:,,,/PrismMetroSample.Infrastructure;Component/Assets/Photos/alter.png" Height="40" UseLayoutRounding="True" RenderOptions.BitmapScalingMode="HighQuality"/>
        <TextBlock  Grid.Column="1" Text="{Binding Message}" HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Row="0" TextWrapping="Wrap"  FontSize="15" FontFamily="Open Sans"/>
    </Grid>
    <Grid Grid.Row="1">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Button Margin="5"  Foreground="White"  FontSize="12" Background="#5cb85c" Command="{Binding CloseDialogCommand}" CommandParameter="true" Content="Yes" Width="64" Height="28" HorizontalAlignment="Right" Grid.Row="1"/>
        <Button Grid.Column="1" Margin="5"  Foreground="White"  FontSize="12" Background="#d9534f" Command="{Binding CloseDialogCommand}" CommandParameter="false" Content="No" Width="64" Height="28" HorizontalAlignment="Left" Grid.Row="1"/>
    </Grid>
   
</Grid>


AlertDialogViewModel.cs:

Copy
public class AlertDialogViewModel : BindableBase, IDialogAware
{

private DelegateCommand<string> _closeDialogCommand;
public DelegateCommand<string> CloseDialogCommand =>
    _closeDialogCommand ?? (_closeDialogCommand = new DelegateCommand<string>(ExecuteCloseDialogCommand));

void ExecuteCloseDialogCommand(string parameter)
{
    ButtonResult result = ButtonResult.None;
    if (parameter?.ToLower() == "true")
        result = ButtonResult.Yes;
    else if (parameter?.ToLower() == "false")
        result = ButtonResult.No;
     RaiseRequestClose(new DialogResult(result));
 }

 //触发窗体关闭事件
 public virtual void RaiseRequestClose(IDialogResult dialogResult)
 {
     RequestClose?.Invoke(dialogResult);
 }

 private string _message;
 public string Message
 {
     get { return _message; }
     set { SetProperty(ref _message, value); }
 }

 private string _title = "Notification";
 public string Title
 {
     get { return _title; }
     set { SetProperty(ref _title, value); }
 }

 public event Action<IDialogResult> RequestClose;

 public bool CanCloseDialog()
 {
     return true;
 }

 public void OnDialogClosed()
 {
        
 }

 public void OnDialogOpened(IDialogParameters parameters)
 {
     Message = parameters.GetValue<string>("message");
 }

}
2.注册对话框#
App.cs:

Copy
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{

 containerRegistry.RegisterDialog<AlertDialog, AlertDialogViewModel>();

}
还可以注册时起名字:

Copy
containerRegistry.RegisterDialog(“alertDialog”);
3.使用对话框服务#
CreateAccountViewModel.cs(修改部分):

Copy
public CreateAccountViewModel(IRegionManager regionManager, IDialogService dialogService)
{

 _regionManager = regionManager;
 _dialogService = dialogService;

}

public void ConfirmNavigationRequest(NavigationContext navigationContext, Action continuationCallback)
{

 if (!string.IsNullOrEmpty(RegisteredLoginId) && this.IsUseRequest)
 {
      _dialogService.ShowDialog("AlertDialog", new DialogParameters($"message={"是否需要用当前注册的用户登录?"}"), r =>
       {
             if (r.Result == ButtonResult.Yes)
                 navigationContext.Parameters.Add("loginId", RegisteredLoginId);
       });
  }
  continuationCallback(true);

}
效果如下:

我们是通过调用IDialogService接口的ShowDialog函数来调用,下面是该接口的定义:

Copy
public interface IDialogService : Object
{

Void Show(String name, IDialogParameters parameters, Action<IDialogResult> callback);
Void ShowDialog(String name, IDialogParameters parameters, Action<IDialogResult> callback);

}
我们可以发现show和ShowDialog函数都是一样形参,无非就是使用场景不一样

name:所要调用对话框view的名字,当注册别名时,只能使用别名来调用
parameters:IDialogParameters接口类型参数,传入的提示消息,通常是$"message={xxxx}"格式,然后再ViewModel的OnDialogOpened函数通过IDialogParameters接口的GetValue函数来获取
callback:用于传入无返回值回调函数
二.自定义对话框窗体#
我们在上述可以看到,对话框的窗体时一个WPF自带的窗体,但是当我们要用自己自定义窗体,例如,去掉window的Icon,保留最大化,最小化和关闭,或者使用一些第三方的窗体控件,prism支持通过注册一个对话框窗体,然后通过再不同对话框的View指定其对话框窗体的style,则可以很灵活的实现不一样的对话框,下面让我们来看看如何操作:

1.注册自定义对话框窗体#
新建一个窗体,DialogWindow.xaml:

Copy

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:PrismMetroSample.Shell.Views.Dialogs"
    mc:Ignorable="d"  
    xmlns:prism="http://prismlibrary.com/"
     >
<Grid>
    
</Grid>


DialogWindow.xaml.cs:

Copy
public partial class DialogWindow : Window, IDialogWindow
{

public DialogWindow()
{
    InitializeComponent();
}

protected override void OnSourceInitialized(EventArgs e)
{
    WindowHelp.RemoveIcon(this);//使用win32函数去除Window的Icon部分
}

public IDialogResult Result { get; set; }

}
App.cs:

Copy
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{

 containerRegistry.RegisterDialogWindow<DialogWindow>();//注册自定义对话框窗体

}
2.自定义对话框窗体Style#
AlertDialog.xaml:

Copy

 <Style TargetType="Window">
      <Setter Property="prism:Dialog.WindowStartupLocation" Value="CenterScreen" />
      <Setter Property="ShowInTaskbar" Value="False"/>
      <Setter Property="SizeToContent" Value="WidthAndHeight"/>
 </Style>


效果如下:

如何我们要将窗体样式全部去掉,改动AlertDialog.xaml:

Copy

 <Style TargetType="Window">
      <Setter Property="prism:Dialog.WindowStartupLocation" Value="CenterScreen" />
      <Setter Property="ShowInTaskbar" Value="False"/>
      <Setter Property="SizeToContent" Value="WidthAndHeight"/>
      <Setter Property="WindowStyle" Value="None"/>
 </Style>


那么就变成了下面这样:

最终,我们的最后效果为这样:

三.小结#
通过Prism的对话框服务,我们可以很好的通过一个IDialogService接口来统一管理对话框的弹出逻辑,而且可以使用依赖注入的模式,如果换成之前要定义一些自定义的对话框,那么也要强依赖View部分,而且可以通过自定义不同对话框的窗体样式,达到一定的灵活性(例如最终效果演示,用了两个不同的对话框样式),至此, .NET Core3.x Prism系列文章已经全部写完

四.源码#
最后,附上整个demo的源代码:PrismDemo源码

作者: RyzenAdorer

出处:https://www.cnblogs.com/ryzen/p/12771986.html

相关文章
|
1月前
|
设计模式 开发框架 JavaScript
基于.NET8 + Vue/UniApp前后端分离的快速开发框架,开箱即用!
基于.NET8 + Vue/UniApp前后端分离的快速开发框架,开箱即用!
|
2月前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
166 3
|
16天前
|
消息中间件 开发框架 监控
NET任务调度框架Hangfire使用指南
Hangfire 是一个用于 .NET 应用程序的开源任务调度框架,支持长时间运行任务、定时任务等。通过简单的安装配置,即可将任务从主线程分离,提升应用性能。支持多种数据库,提供丰富的任务类型如立即执行、延迟执行和周期性任务,并有可视化管理界面 Hangfire Dashboard。还支持安全性配置及扩展插件,如 Hangfire.HttpJob,适合各种复杂场景下的任务调度需求。
42 1
NET任务调度框架Hangfire使用指南
|
1月前
|
开发框架 安全 .NET
在数字化时代,.NET 技术凭借跨平台兼容性、丰富的开发工具和框架、高效的性能及强大的安全稳定性,成为软件开发的重要支柱
在数字化时代,.NET 技术凭借跨平台兼容性、丰富的开发工具和框架、高效的性能及强大的安全稳定性,成为软件开发的重要支柱。它不仅加速了应用开发进程,提升了开发质量和可靠性,还促进了创新和业务发展,培养了专业人才和技术社区,为软件开发和数字化转型做出了重要贡献。
27 5
|
1月前
|
传感器 人工智能 供应链
.NET开发技术在数字化时代的创新作用,从高效的开发环境、强大的性能表现、丰富的库和框架资源等方面揭示了其关键优势。
本文深入探讨了.NET开发技术在数字化时代的创新作用,从高效的开发环境、强大的性能表现、丰富的库和框架资源等方面揭示了其关键优势。通过企业级应用、Web应用及移动应用的创新案例,展示了.NET在各领域的广泛应用和巨大潜力。展望未来,.NET将与新兴技术深度融合,拓展跨平台开发,推动云原生应用发展,持续创新。
35 4
|
1月前
|
开发框架 .NET C#
.NET 技术凭借高效开发环境、强大框架支持及跨平台特性,在软件开发中占据重要地位
.NET 技术凭借高效开发环境、强大框架支持及跨平台特性,在软件开发中占据重要地位。从企业应用到电子商务,再到移动开发,.NET 均展现出卓越性能,助力开发者提升效率与项目质量,推动行业持续发展。
32 4
|
1月前
|
消息中间件 监控 数据可视化
基于.NET开源、功能强大且灵活的工作流引擎框架
基于.NET开源、功能强大且灵活的工作流引擎框架
|
1月前
|
开发框架 网络协议 .NET
C#/.NET/.NET Core优秀项目和框架2024年10月简报
C#/.NET/.NET Core优秀项目和框架2024年10月简报
|
1月前
|
存储 设计模式 编解码
.NET 8.0 通用管理平台,支持模块化、WinForms 和 WPF
【11月更文挑战第5天】本文分析了.NET 8.0 通用管理平台在模块化、WinForms 和 WPF 方面的优势。模块化设计提升了系统的可维护性和可扩展性,提高了代码复用性;WinForms 提供了丰富的控件库和简单易用的开发模式,技术成熟稳定;WPF 支持强大的数据绑定和 MVVM 模式,具备丰富的图形和动画功能,以及灵活的布局系统。
|
1月前
|
网络协议 Unix Linux
精选2款C#/.NET开源且功能强大的网络通信框架
精选2款C#/.NET开源且功能强大的网络通信框架