本文将介绍如何在.NET Core3环境下使用MVVM框架Prism的对话框服务,这也是prism系列的最后一篇完结文章,下面是Prism系列文章的索引:
.NET Core 3 WPF MVVM框架 Prism系列之文章索引
一.对话框服务
在Prism中,通过一个IDialogAware接口来实现对话框服务:
public interface IDialogAware
{
bool CanCloseDialog();
void OnDialogClosed();
void OnDialogOpened(IDialogParameters parameters);
string Title { get; set; }
event Action RequestClose;
}
- CanCloseDialog()函数是决定窗体是否关闭
- OnDialogClosed()函数是窗体关闭时触发,触发条件取决于CanCloseDialog()函数
- OnDialogOpened()函数时窗体打开时触发,比窗体Loaded事件早触发
- Title为窗体的标题
- RequestClose为关闭事件,可由此控制窗体的关闭
1.创建对话框的View和ViewModel
AlertDialog.xaml:
AlertDialogViewModel.cs:
public class AlertDialogViewModel : BindableBase, IDialogAware
{
private DelegateCommand _closeDialogCommand;
public DelegateCommand CloseDialogCommand =>
_closeDialogCommand ?? (_closeDialogCommand = new DelegateCommand(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 RequestClose;
public bool CanCloseDialog()
{
return true;
}
public void OnDialogClosed()
{
}
public void OnDialogOpened(IDialogParameters parameters)
{
Message = parameters.GetValue("message");
}
}
2.注册对话框
App.cs:
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterDialog();
}
还可以注册时起名字:
containerRegistry.RegisterDialog(“alertDialog”);
3.使用对话框服务
CreateAccountViewModel.cs(修改部分):
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函数来调用,下面是该接口的定义:
public interface IDialogService : Object
{
Void Show(String name, IDialogParameters parameters, Action callback);
Void ShowDialog(String name, IDialogParameters parameters, Action callback);
}
我们可以发现show和ShowDialog函数都是一样形参,无非就是使用场景不一样
- name:所要调用对话框view的名字,当注册别名时,只能使用别名来调用
- parameters:IDialogParameters接口类型参数,传入的提示消息,通常是$"message={xxxx}"格式,然后再ViewModel的OnDialogOpened函数通过IDialogParameters接口的GetValue函数来获取
- callback:用于传入无返回值回调函数
二.自定义对话框窗体
我们在上述可以看到,对话框的窗体时一个WPF自带的窗体,但是当我们要用自己自定义窗体,例如,去掉window的Icon,保留最大化,最小化和关闭,或者使用一些第三方的窗体控件,prism支持通过注册一个对话框窗体,然后通过再不同对话框的View指定其对话框窗体的style,则可以很灵活的实现不一样的对话框,下面让我们来看看如何操作:
1.注册自定义对话框窗体
新建一个窗体,DialogWindow.xaml:
DialogWindow.xaml.cs:
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:
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterDialogWindow();//注册自定义对话框窗体
}
2.自定义对话框窗体Style
AlertDialog.xaml:
效果如下:
如何我们要将窗体样式全部去掉,改动AlertDialog.xaml:
那么就变成了下面这样:
最终,我们的最后效果为这样:
三.小结
通过Prism的对话框服务,我们可以很好的通过一个IDialogService接口来统一管理对话框的弹出逻辑,而且可以使用依赖注入的模式,如果换成之前要定义一些自定义的对话框,那么也要强依赖View部分,而且可以通过自定义不同对话框的窗体样式,达到一定的灵活性(例如最终效果演示,用了两个不同的对话框样式),至此, .NET Core3.x Prism系列文章已经全部写完
四.源码
最后,附上整个demo的源代码:PrismDemo源码