Prism弹窗
创建弹窗
创建弹窗内容
创建一个弹出窗口的内容:一般是UserControl(不是Window)
<UserControl x:Class="Zhaoxi.PrismDialog.UCDetail"
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:Zhaoxi.PrismDialog"
xmlns:p="http://prismlibrary.com/"
mc:Ignorable="d" FontSize="20" Foreground="Orange"
d:DesignHeight="450" d:DesignWidth="800"
Height="300" Width="500">
<p:Dialog.WindowStyle>
<Style TargetType="Window">
<Setter Property="Width" Value="500"/>
<Setter Property="Height" Value="300"/>
<Setter Property="WindowChrome.WindowChrome">
<Setter.Value>
<WindowChrome GlassFrameThickness="-1"/>
</Setter.Value>
</Setter>
</Style>
</p:Dialog.WindowStyle>
<StackPanel>
<TextBlock Text="弹出窗口内容"/>
<TextBox Text="{Binding Value,UpdateSourceTrigger=PropertyChanged}"/>
<Button Content="Close" Command="{Binding CloseCommand}"/>
</StackPanel>
</UserControl>
使用Prism框架提供的Dialog.WindowStyle属性,修改窗体的样式
在UserControl中设置Height和Width属性,修改弹窗的初始大小
注册弹窗
对应的ViewModel实现IDialogAware接口
public partial class UCDetail : UserControl
{
public UCDetail(IContainerProvider containerProvider)
{
InitializeComponent();
this.DataContext = new DetailViewModel();
}
}
public class DetailViewModel : BaseVM, IDialogAware
{
// 弹出窗口的标题
public string Title => "Hello Dialog";
// 执行关闭返回
public event Action<IDialogResult> RequestClose;
// 当前打开的窗口是否允许关闭
public bool CanCloseDialog()
{
return true;
}
// 当弹出窗口关闭时执行的逻辑
public void OnDialogClosed()
{
}
// 当弹出窗口打开的时候执行的逻辑
public void OnDialogOpened(IDialogParameters parameters)
{
}
}
在RegisterTypes方法中注册弹窗
public partial class App : PrismApplication
{
protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
// 注册弹窗内容
containerRegistry.RegisterDialog<UCDetail>("AAAA");
}
}
调用弹窗
注入IDialogService,使用ShowDialog方法调用弹窗
public MainViewModel(IEventAggregator eventAggregator, IDialogService dialogService)
{
_dialogService = dialogService;
OpenCommand = new DelegateCommand(OnOpen);
}
public DelegateCommand OpenCommand { get; set; }
private void OnOpen()
{
//每次打开都是新的实例
_dialogService.ShowDialog("AAAA");
}
创建弹窗窗口
对应的Window的窗口需要实现IDialogWindow接口
public partial class DialogParent : Window, IDialogWindow
{
public DialogParent()
{
InitializeComponent();
}
public IDialogResult Result { get; set; }
}
修改弹窗窗口样式
Title改为绑定
<Window x:Class="Zhaoxi.PrismDialog.DialogParent"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Zhaoxi.PrismDialog"
mc:Ignorable="d" SizeToContent="WidthAndHeight"
Title="{Binding Title}" Height="450" Width="800">
<Window.Template>
<ControlTemplate TargetType="Window">
<Border CornerRadius="10" Background="Orange" Margin="5">
<Border.Effect>
<DropShadowEffect BlurRadius="10" Color="Gray" ShadowDepth="0" Opacity="0.3"/>
</Border.Effect>
<ContentPresenter/>
</Border>
</ControlTemplate>
</Window.Template>
</Window>
RegisterTypes中注册弹窗窗口即可
public partial class App : PrismApplication
{
protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
// 注册弹窗内容
containerRegistry.RegisterDialog<UCDetail>("AAAA");
// 注册弹窗窗口,这句代码会将框架内的默认弹窗窗口替换掉
//弹窗窗体别名"fwefewfe",可以不填默认RegisterDialogWindow中填入的泛型名称-"DialogParent"
containerRegistry.RegisterDialogWindow<DialogParent>("fwefewfe");
}
}
// 4、可以根据注册Dialog窗口的名称,使用特定的窗口对象
// 注册的窗口名称,如果指定了,在容器中必须存在这个名称的
// 否则报错:Exception:No registered type IDialogWindow with the key fwefewfe.
_dialogService.ShowDialog("AAAA", param, OnDialogClosed, "fwefewfe");
弹窗参数请求
弹窗传进参数
使用IDialogService提供的ShowDialog方法实现参数拆传递
// 摘要:
// Shows a modal dialog.
// 显示模式对话框
// 参数:
// name:
// The name of the dialog to show.
// 要显示的对话框的名称。
// parameters:
// The parameters to pass to the dialog.
// 要传递给对话框的参数。
// callback:
// The action to perform when the dialog is closed.
// 对话框关闭时要执行的操作。
void ShowDialog(string name, IDialogParameters parameters, Action<IDialogResult> callback);
创建DialogParameters对象,并加入参数体
param.Add(参数名称, 参数内容)
private void OnOpen()
{
DialogParameters param = new DialogParameters();
param.Add("svsdvsf", "Hello Dialog");
_dialogService.ShowDialog("AAAA", param, OnDialogClosed);
}
private void OnDialogClosed(IDialogResult result)
{
}
弹窗对应的ViewModel中取出参数
// 当弹出窗口打开的时候执行的逻辑
public void OnDialogOpened(IDialogParameters parameters)
{
string arg = parameters.GetValue<string>("svsdvsf");
}
弹窗返回参数
DialogResult创建对象,并加入参数体
触发IDialogAware提供的事件RequestClose触发回调,调用_dialogService.ShowDialog("AAAA", param, OnDialogClosed)中OnDialogClosed方法体
public DelegateCommand CloseCommand { get; set; }
public DetailViewModel()
{
CloseCommand = new DelegateCommand(OnClose);
}
private void OnClose()
{
IDialogResult dialogResult = new DialogResult();
dialogResult.Parameters.Add("A", true);
RequestClose?.Invoke(dialogResult);
}
弹窗中的区域注册
编写三个页面测试
MainView页面打开弹窗
<Window x:Class="Zhaoxi.PrismRegion.NewRegion.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Zhaoxi.PrismRegion.NewRegion.Views"
xmlns:p="http://prismlibrary.com/"
mc:Ignorable="d" FontSize="20"
Title="MainView" Height="450" Width="800">
<Grid>
<ContentControl p:RegionManager.RegionName="MainRegion"/>
<Button Content="打开弹窗" Command="{Binding ShowDialogCommand}"/>
</Grid>
</Window>
DialogView页面命名一个区域和加载区域的Command
ViewModel继承IDialogAware接口,初始化的时初始化DelegateCommand
<UserControl x:Class="Zhaoxi.PrismRegion.NewRegion.Views.DialogView"
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:Zhaoxi.PrismRegion.NewRegion.Views"
xmlns:p="http://prismlibrary.com/"
mc:Ignorable="d" FontSize="20"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Button Content="加载页面" Command="{Binding ShowViewCommand}"
VerticalAlignment="Top"/>
<ContentControl p:RegionManager.RegionName="DialogRegion"
Margin="0,30,0,0"/>
</Grid>
</UserControl>
public class DialogViewModel : IDialogAware
{
public string Title => "";
public event Action<IDialogResult> RequestClose;
public bool CanCloseDialog()
{
return true;
}
public void OnDialogClosed()
{
}
public void OnDialogOpened(IDialogParameters parameters)
{
}
public DelegateCommand ShowViewCommand { get; set; }
public DialogViewModel(IRegionManager regionManager)
{
ShowViewCommand = new DelegateCommand(() =>
{
// 打开SubView
regionManager.RequestNavigate("DialogRegion", "SubView");
});
}
}
运行后点击加载页面后显示失败
查看regionManager的属性发现只有MainView的MainRegion区域被注册
因为Prism框架会默认扫描CreateShell方法返回的窗体区域进行注册,但弹窗是后续初始化,并不会注册区域所以显示失败
在DialogView初始哈的时候注入IRegionManager
注册区域:RegionManager.SetRegionManager(this, regionManager);
刷新区域:RegionManager.UpdateRegions();
订阅弹窗的Unloaded事件,弹窗关闭时移除注册区域防止下次初始化时报错:区域已注册
/// <summary>
/// DialogView.xaml 的交互逻辑
/// </summary>
public partial class DialogView : UserControl
{
public DialogView(IRegionManager regionManager)
{
InitializeComponent();
RegionManager.SetRegionManager(this, regionManager);
RegionManager.UpdateRegions();
this.Unloaded += DialogView_Unloaded;
}
private void DialogView_Unloaded(object sender, RoutedEventArgs e)
{
var rm = RegionManager.GetRegionManager(this);
rm.Regions.Remove("DialogRegion");
}
}
运行后,regionManager中注册有两个区域
加载成功