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

關於視窗彈出效果:
效果一般,如果有設計師可以做得漂亮。
本文不打算寫得太詳細,具體做法可以看原始碼(文末附倉庫連結),另外關於 Prism 的學習可參考以下文章:
- NET Core 3.x WPF MVVM 框架 Prism 系列(後續版本通用)
https://dotnet9.com/album/wpf-prism
- 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編寫的,只有這樣才能套入一個Window的RegisterDialogWindow內。
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}}"/>
命令參數AddLogView即2.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