.NET Core 3 WPF MVVM框架 Prism系列之對話方塊服務
阿新 • • 發佈:2020-04-26
本文將介紹如何在.NET Core3環境下使用MVVM框架Prism的對話方塊服務,這也是prism系列的最後一篇完結文章,下面是Prism系列文章的索引:
[.NET Core 3 WPF MVVM框架 Prism系列之文章索引]( https://www.cnblogs.com/ryzen/p/12610249.html )
## 一.對話方塊服務
在Prism中,通過一個**IDialogAware**介面來實現對話方塊服務:
```c#
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:
```c#
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:
```c#
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterDialog();
}
```
還可以註冊時起名字:
```c#
containerRegistry.RegisterDialog(“alertDialog”);
```
## 3.使用對話方塊服務
CreateAccountViewModel.cs(修改部分):
```c#
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);
}
```
效果如下:
![](https://img2020.cnblogs.com/blog/1294271/202004/1294271-20200425110035649-1492786654.gif)
我們是通過呼叫IDialogService介面的ShowDialog函式來呼叫,下面是該介面的定義:
```c#
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:
```c#
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:
```c#
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterDialogWindow();//註冊自定義對話方塊窗體
}
```
### 2.自定義對話方塊窗體Style
AlertDialog.xaml:
```
```
效果如下:
![](https://img2020.cnblogs.com/blog/1294271/202004/1294271-20200425110046765-478758847.png)
如何我們要將窗體樣式全部去掉,改動AlertDialog.xaml:
```
```
那麼就變成了下面這樣:
![](https://img2020.cnblogs.com/blog/1294271/202004/1294271-20200425110054233-1478722232.png)
最終,我們的最後效果為這樣:
![](https://img2020.cnblogs.com/blog/1294271/202004/1294271-20200425110019829-1513316948.gif)
## 三.小結
通過Prism的對話方塊服務,我們可以很好的通過一個IDialogService介面來統一管理對話方塊的彈出邏輯,而且可以使用依賴注入的模式,如果換成之前要定義一些自定義的對話方塊,那麼也要強依賴View部分,而且可以通過自定義不同對話方塊的窗體樣式,達到一定的靈活性(例如最終效果演示,用了兩個不同的對話方塊樣式),至此, .NET Core3.x Prism系列文章已經全部寫完
## 四.原始碼
最後,附上整個demo的原始碼:[PrismDemo原始碼]( https://github.com/ZhengDaoWang/PrismMetro