如何在 Prism 的 Module 中彈出對話方塊?

如何在 Prism 的 Module 中彈出對話方塊?

有網友提出需求,在Prism的Module中如何彈出對話方塊?像主界面彈出關於對話方塊一樣?

最後更新 2021/4/14 下午5:32
沙漠尽头的狼
預計閱讀 5 分鐘
分類
WPF
專題
WPF MVVM框架 Prism系列
標籤
.NET WPF Prism Module

有網友提出需求,在 Prism 的 Module 中如何彈出對話方塊?像主介面彈出關於對話方塊一樣?

網友需求

關於視窗彈出效果:

效果一般,如果有設計師可以做得漂亮。

本文不打算寫得太詳細,具體做法可以看原始碼(文末附倉庫連結),另外關於 Prism 的學習可參考以下文章:

  1. NET Core 3.x WPF MVVM 框架 Prism 系列(後續版本通用)
https://dotnet9.com/album/wpf-prism
  1. WPF 企業級開發框架搭建指南(啟示錄),2020 從入門到放棄
https://jhrs.com/2020/37391.html

1 關於對話方塊如何彈出來的?

1.1 通用對話方塊視窗註冊

App.xaml.cs

protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
  ...
  containerRegistry.RegisterDialogWindow<DialogWindow>();//註冊自訂對話方塊視窗
  ...
}

如上程式碼,RegisterDialogWindow為註冊對話方塊視窗程式碼,即所有彈出的對話方塊是包裹在DialogWindow內的,程式碼簡單我就不貼了,知道它是一個Window就好,具體請看原始碼:DialogWindow

1.2 實際對話方塊註冊

也是在 App.xaml.cs 檔案中,下面的程式碼即為註冊實際的對話方塊程式碼:QQ群對話方塊關於對話模式推薦網站對話方塊等,括號中的字串(如"About")用於彈出對話方塊定位使用,註:實際的對話方塊是基於UserControl編寫的,只有這樣才能套入一個WindowRegisterDialogWindow

protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
  ...
  containerRegistry.RegisterDialogWindow<DialogWindow>();//註冊自訂對話方塊視窗
  containerRegistry.RegisterDialog<QQGroupView, QQGroupViewModel>("QQGroup");
  containerRegistry.RegisterDialog<AboutView, AboutViewModel>("About");
  containerRegistry.RegisterDialog<WebView, WebViewModel>("Web");
  ...
}

1.3 功能表觸發調出對話方塊

這個就更簡單了,直接在 xaml 中使用,比如主視窗的關於功能表:

<menuitem
  Command="{Binding RaiseShowDialogCommand}"
  CommandParameter="About"
  Header="{markup:I18n {x:Static i18NResources:Language.About}}"
>
  <MenuItem.Icon>
    <Path
      Width="16"
      Data="{StaticResource InfoGeometry}"
      Fill="{DynamicResource SuccessBrush}"
    />
  </MenuItem.Icon>
</menuitem>

RaiseShowDialogCommand在 VM 的基底類別ViewModelBase定義的,實際呼叫程式碼如下:

/// <summary>
/// 顯示對話方塊
/// </summary>
/// <param name="dlgName"></param>
private void RaiseShowDialogHandler(string dlgName)
{
  DialogService.ShowDialog(dlgName);
}

參數dlgName即上面1.2註冊對話方塊時指定的字串,視情況指定。

2 Module 中的對話方塊如何彈出?

這一節就是本文的重點了。

2.1 關鍵:IModule 的 RegisterTypes 方法

Module是動態載入的,模組中的對話方塊不可能寫在App.xaml.cs中吧?如果你對Prism比較熟悉,看看各模組的Module進入點類別,即繼承IModule的模組進入點類別方法RegisterTypes(IContainerRegistry containerRegistry),可以在這裡注入模組使用的型別和對話方塊,供本模組或者其他模組使用。

2.2 模組對話方塊實作

LQClass.ModuleOfLog模組為例,我們在下面註冊新增日誌對話方塊:

public void RegisterTypes(IContainerRegistry containerRegistry)
{
  ...
  containerRegistry.RegisterDialog<AddView, AddViewModel>("AddLogView");
  ...
}

AddView為新增日誌檢視,和一般使用者控制項沒有區別,可參考關於對話方塊編寫,本專案檢視連結見AddView.xaml

2.3 怎麼呼叫?

呼叫方式同主視窗功能表一致,程式碼檔案路徑:src\LQClass.AdminForWPF\Modules\LQClass.ModuleOfLog\Views新增按鈕宣告如下:

<Button
  Margin="10,15,10,0"
  Style="{StaticResource ButtonSuccess}"
  Command="{Binding RaiseShowDialogCommand}"
  CommandParameter="AddLogView"
  Content="{markup:I18n {x:Static i18NResources:Language.Add}}"/>

命令參數AddLogView2.2中註冊檢視時給的名稱。

效果如下,只是示範模組中如何彈出對話方塊,未加實際業務:

3 關於專案怎麼執行?

說明:本專案服務端基於WTM搭建,用戶端由 WPF 編寫。

3.1 執行服務端

如果需要執行檢視用戶端效果,請先編譯服務端src\LQClass.Admin,至於怎麼編譯,不會的請自行搜尋,編譯成功後,偵錯執行服務端專案,或者雙擊執行服務端 Exe:src\LQClass.Admin\LQClass.Admin\bin\Debug\net5.0\LQClass.Admin.exe,服務端預設開啟 5000 埠。

3.2 執行 WPF 用戶端

如果只是看原始碼,可以忽略本步驟。

注意查看App.config,用戶端連接服務端的位址是否正確:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
	<appSettings>
    ...
		<add key="API" value="http://localhost:5000/api/"/>
	</appSettings>
  ...
</configuration>

專案路徑:src\LQClass.AdminForWPF,產生成功,偵錯用戶端專案,或者雙擊用戶端 Exe:\src\LQClass.AdminForWPF\Build\LQClass.AdminForWPF.exe即可執行本用戶端了。

後端預設管理員帳號:

admin
000000

最後來個完整示範:

倉庫(歡迎提 issue):https://github.com/dotnet9/lqclass.com

繼續探索

延伸閱讀

更多文章