WPF MVVM框架 - Prism IDialogService 对话服务
在 WPF Prism 框架中,IDialogService 是一种用于实现对话框交互的服务,遵循 MVVM 模式,允许在 ViewModel 中管理对话框逻辑而无需直接操作视图。
基本概念
解耦性: 通过依赖注入实现 ViewModel 与对话框视图的解耦。
对话框类型: 支持模态和非模态对话框。
生命周期管理: 自动处理对话框的创建、显示和销毁
创建对话框 View
<UserControl x:Class="Prism_Base.Views.SwitchAccountDialogControl"
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:Prism_Base.Views"
mc:Ignorable="d"
d:DesignHeight="150" d:DesignWidth="300" Background="White">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="30"/>
<RowDefinition Height="15"/>
</Grid.RowDefinitions>
<TextBlock Text="当前账号会登出,确定切换账号?" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center">
<Button Content="确定" Width="100" Margin="4" Command="{Binding confirmCommand}"/>
<Button Content="取消" Width="100" Margin="4" Command="{Binding cancelCommand}"/>
</StackPanel>
</Grid>
</UserControl>
创建对话框 ViewModel
public class SwitchAccountDialogControlViewModel : BindableBase, IDialogAware
{
public DelegateCommand confirmCommand { get; private set; }
public DelegateCommand cancelCommand { get; private set; }
public DialogResult dialogResult { get; private set; }
public SwitchAccountDialogControlViewModel()
{
confirmCommand = new DelegateCommand(Confirm);
cancelCommand = new DelegateCommand(OnDialogClosed);
}
public DialogCloseListener RequestClose { get; }
public bool CanCloseDialog()
{
return true;
}
public void OnDialogClosed()
{
RequestClose.Invoke(dialogResult);
}
public void OnDialogOpened(IDialogParameters parameters)
{
if (parameters.ContainsKey("param1"))
{
var param1 = parameters["param1"];
}
}
public void Confirm()
{
dialogResult = new DialogResult(ButtonResult.OK);
var parameters = new DialogParameters();
parameters.Add("result", "ok");
dialogResult.Parameters = parameters;
OnDialogClosed();
}
public void cancel()
{
dialogResult = new DialogResult(ButtonResult.No);
var parameters = new DialogParameters();
parameters.Add("result", "ok");
dialogResult.Parameters = parameters;
OnDialogClosed();
}
}注册对话框服务
在 App.xaml.cs 中的 RegisterTypes 方法内注册对话服务
public partial class App : PrismApplication
{
protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<MainWindow, MainWindowViewModel>();
containerRegistry.RegisterForNavigation<CustomerManagerControl, CustomerManagerControlViewModel>();
containerRegistry.RegisterForNavigation<SkuManagerControl, SkuManagerControlViewModel>();
containerRegistry.RegisterForNavigation<SystemManagerControl, SystemManagerControlViewModel>();
// 注册对话服务
containerRegistry.RegisterDialog<SwitchAccountDialogControl, SwitchAccountDialogControlViewModel>();
}
}打开对话框
注入IDialogService接口,调用 Show 方法打开对话框,传递参数,编写回调事件
public class MainWindowViewModel : BindableBase
{
public DelegateCommand<string> NavigateCommand { get; private set; }
public DelegateCommand SwitchAccountCommand { get; private set; }
private readonly IRegionManager _regionManager;
private readonly IDialogService _dialogService;
public MainWindowViewModel(IRegionManager regionManager, IDialogService dialogService)
{
NavigateCommand = new DelegateCommand<string>(Navigate);
SwitchAccountCommand = new DelegateCommand(SwitchAccount);
_regionManager = regionManager;
_dialogService = dialogService;
}
public void Navigate(string viewName)
{
_regionManager.RequestNavigate("ContentRegion", viewName);
}
public void SwitchAccount()
{
var parameters = new DialogParameters();
parameters.Add("param1", "value1");
_dialogService.Show("SwitchAccountDialogControl", parameters, result =>
{
if (result.Result == ButtonResult.OK)
{
// 确定
Application.Current.Shutdown();
}
else
{
// 取消
}
});
}
}常见问题排查
对话框未显示:
确保已正确注册对话框 RegisterDialog<MyDialog, MyDialogViewModel>()。
检查对话框名称是否匹配 ShowDialog("MyDialog")。
参数未接收:
检查发送和接收的键名是否一致。
确认 ViewModel 实现了 IDialogAware 并在 OnDialogOpened 中处理参数。
对话框关闭无响应:
确保调用了 RequestClose.Invoke(result)。
检查 ButtonResult 是否正确设置(如 ButtonResult.OK)。