protected override Window CreateShell()
return Container.Resolve<NavigationWindow>();
Region
如果只更新数据源,UI不变则可以使用prism:RegionManager.RegionContext=""
一般的WPF容器是无法创建Region的,例如:Grid,UniformGrid,DockPanel,Canvas等。
可以创建Region的,例如:
ContentControl,只能显示一个,所有内容都是堆叠的。
ItemsControl,所有内容都是栈的形式布局的,类似StackPanel
ComboBox,所有内容,类似下拉框,下拉列表。
TabControl,类似TabControl控件
总结:具有RegionAdapter才可以创建Region,可以自定义Region
ContentControl->ContentControlRegionAdapter
ItemsControl->ItemsControlRegionAdapter
ComboBox->SelectorRegionAdapter
TabControl->TabControlRegionAdapter
Region的多种注册方式
第一种:Xaml方式注册
<!--第一种情况,Xaml方式注册一个区域-->
<!--<ContentControl prism:RegionManager.RegionName="ContentRegion"/>-->
第二种通过C#代码注册
Region中的都是UserControl,所以应该是创建一个ViewA,然后再添加到Region中。
<!--第二种方式,代码注册-->
<ContentControl Name="cc"/>
public MainWindow(IRegionManager regionManager)
InitializeComponent();
RegionManager.SetRegionName(this.cc, "ContentRegion");
/// 将相关View指定到特定的Region
/// 第一个参数:Region的名称
/// 第二个参数:View的类型
regionManager.RegisterViewWithRegion("ContentRegion", typeof(ViewA));
创建自己的RegionAdapter
定义RegionAdapter
public class StackPanelRegionAdapter : RegionAdapterBase<StackPanel>
public StackPanelRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory) : base(regionBehaviorFactory)
protected override void Adapt(IRegion region, StackPanel regionTarget)
region.Views.CollectionChanged += (se, ev) =>
if (ev.Action == NotifyCollectionChangedAction.Add)
foreach (UIElement item in ev.NewItems)
regionTarget.Children.Add(item);
protected override IRegion CreateRegion() => new AllActiveRegion();
注册RegionAdapter
public partial class App : PrismApplication
protected override Window CreateShell()
return Container.Resolve<NavigationWindow>();
protected override void ConfigureRegionAdapterMappings(RegionAdapterMappings regionAdapterMappings)
base.ConfigureRegionAdapterMappings(regionAdapterMappings);
regionAdapterMappings.RegisterMapping<StackPanel>(Container.Resolve<StackPanelRegionAdapter>());
Region视图切换、Activate
Activate&Deactivate有针对,并不是所有Adapter适用,例如:ContentControlRegionAdapter可以,如果使用ItemsControlRegionAdapter则会报错。
Region视图切换,Navigation。
构造函数注入IRegionManager,IContainerExtension
取出Region,_regionManager.Regions["ContentRegion"];
添加view
导航到指定view
Activate&Deactivate有针对,并不是所有Adapter适用,ContentControlRegionAdapter可以,但是ItemsControlRegionAdapter->报错。
public partial class MainView : Window
IRegionManager _regionManager;
IContainerExtension _containerExtension;
ViewB viewB;
public MainView(IRegionManager regionManager, IContainerExtension containerExtension)
InitializeComponent();
_regionManager = regionManager;
_containerExtension = containerExtension;
/// Region视图切换
/// Activete&Deactivated
/// 视图切换-》另一种方式:Navigation
this.Loaded += (se, ev) =>
var _region = _regionManager.Regions["ContentRegion"];
viewB = _containerExtension.Resolve<ViewB>();
_region.Add(_containerExtension.Resolve<ViewA>());
_region.Add(viewB);
private void Button_Click(object sender, RoutedEventArgs e)
var _region = _regionManager.Regions["ContentRegion"];
_region.Activate(ViewB);
// Activate&Deactivate有针对,并不是所有Adapter适用
// ContentControlRegionAdapter
// ItemsControlRegionAdapter->报错
判断View是否是活跃状态
继承BindableBase, IActiveAware
public class ViewAViewModel : BindableBase, IActiveAware,
private bool _isActive;
public bool IsActive
get => _isActive;
_isActive = value;
if (value)
System.Diagnostics.Debug.WriteLine("ViewA 激活了");
System.Diagnostics.Debug.WriteLine("ViewA 失效了");
IsActiveChanged?.Invoke(this, new EventArgs());
public event EventHandler IsActiveChanged;
Navigation
Navigation控制View切换,
写View的UI代码
写ViewModels的代码
写对应的Cmd方法
注入View,App.cs 中的RegisterTypes,注入VIew,containerRegistry.RegisterForNavigation<ViewA>();
ViewModel的构造函数中注入IRegionManager,需要的导航到指定的View:_regionManager.RequestNavigate("ContentRegion", "ViewB");
如果是Module形式的注册,则可以在Module类中通过RegisterForNavigation注册
public class SysModule : IModule
public void OnInitialized(IContainerProvider containerProvider)
public void RegisterTypes(IContainerRegistry containerRegistry)
containerRegistry.RegisterForNavigation<MenuManagementView>("mmView");
containerRegistry.RegisterForNavigation<UserManagementView>();
containerRegistry.RegisterDialog<UserEditView>();
第一种:基本导航
_regionManager.RequestNavigate("ContentRegion", "ViewB");
第二种:使用参数替代字符串的导航
<Button Content="ViewA" Command="{Binding ViewACommand}" CommandParameter="ViewA"/>
private DelegateCommand<string> _viewACommand;
public DelegateCommand<string> ViewACommand
if (_viewACommand == null)
_viewACommand = new DelegateCommand<string>((view) =>
_regionManager.RequestNavigate("ContentRegion", view);
return _viewACommand;
set { _viewACommand = value; }
第三种:使用TabControl
ViewModel增加属性Title
绑定到View
和第二中方法的导航一样可以注册到指定的Region内
<Window.Resources>
<Style TargetType="TabItem">
<Setter Property="Header" Value="{Binding DataContext.Title}"/>
</Style>
</Window.Resources>
<TabControl prism:RegionManager.RegionName="ContentRegion" Grid.Row="1"/>
第四种:判断窗口是否重现还是新增
继承INavigationAware,IsNavigationTarget方法控制
INavigationAware,实现三个接口方法
IsNavigationTarget:View是重现(返回True)还是新建(返回False)
OnNavigatedTo:导航传值,导航日志
OnNavigatedFrom:从这个页面到那个页面,关注的是出发时机。
第五种:导航传值
NavigationWindowViewModel中的ViewACommand传参
ViewA中接收参数,OnNavigatedTo中:var param = navigationContext.Parameters["value"];
//NavigationWindowViewModel中的Command
private DelegateCommand<string> _viewACommand;
public DelegateCommand<string> ViewACommand
if (_viewACommand == null)
_viewACommand = new DelegateCommand<string>((view) =>
// 导航到 ViewA
// 传值
// 导航某个页面,添加判断,是否是可以导航过去
NavigationParameters param = new NavigationParameters();
param.Add("value", "123");
_regionManager.RequestNavigate("ContentRegion", view,param);
return _viewACommand;
set { _viewACommand = value; }
//ViewA中的OnNavigatedTo
public void OnNavigatedTo(NavigationContext navigationContext)
// 导航传值
var param = navigationContext.Parameters["value"];
// 历史记录
_journal = navigationContext.NavigationService.Journal;
//_journal.GoForward();
//_journal.GoBack();
public bool IsNavigationTarget(NavigationContext navigationContext)
// 控件View是重现(返回True)还是新建(返回False)
return true;
public void OnNavigatedFrom(NavigationContext navigationContext)
// navigationContext可以拿ViewA和ViewB两个对象
// 触发时机
第六种:导航日志控制导航
ViewAViewModel继承INavigationAware,实现对应的OnNavigatedTo
向前:journal.GoForward();
向后:journal.GoBack();
ViewAViewModel实现字段IRegionNavigationJournal _journal;
添加一个Command调用_journal.GoBack();回到之前的页面
也可以NavigationWindowViewModel构造函数注入,_regionManager也可以达到相同的控制效果
构造函数注入:IRegionNavigationService
实现ForwordCommand、BackCommand
_regionManager也可以达到相同的控制效果
IRegionManager _regionManager;
IRegionNavigationService _regionNavigationService;
public NavigationWindowViewModel(IRegionManager regionManager, IRegionNavigationService regionNavigationService)
_regionManager = regionManager;
_regionNavigationService = regionNavigationService;
private DelegateCommand _forwordCommand;
public DelegateCommand ForwordCommand
if (_forwordCommand == null)
_forwordCommand = new DelegateCommand(() =>
//if (_regionNavigationJournal.CanGoForward)
// _regionNavigationJournal.GoForward();
var j = _regionManager.Regions["ContentRegion"].NavigationService.Journal;
//var j = _regionNavigationService.Journal;
if (j.CanGoForward)
j.GoForward();
return _forwordCommand;
set { _forwordCommand = value; }
private DelegateCommand _backCommand;
public DelegateCommand BackCommand
if (_backCommand == null)
_backCommand = new DelegateCommand(() =>
//var j = _regionNavigationService.Journal;
var j = _regionManager.Regions["ContentRegion"].NavigationService.Journal;
if (j.CanGoBack)
j.GoBack();
return _backCommand;
set { _backCommand = value; }
IRegionNavigationJournal _journal;
public DelegateCommand GoBackCommand { get; set; }
public ViewAViewModel()
this.Title = "VIewA";
GoBackCommand = new DelegateCommand(GoBack);
private void GoBack()
_journal.GoBack();
public void OnNavigatedTo(NavigationContext navigationContext)
// 导航传值
var param = navigationContext.Parameters["value"];
// 历史记录
_journal = navigationContext.NavigationService.Journal;
//_journal.GoForward();
//_journal.GoBack();
第七种:判断导航是否结束
_regionManager.RequestNavigate第三个参数表示导航结束,可以写个Action进行处理,是导航的最后一站。
private DelegateCommand<string> _viewACommand;
public DelegateCommand<string> ViewACommand
if (_viewACommand == null)
_viewACommand = new DelegateCommand<string>((view) =>
// 导航到 ViewA
// 传值
// 导航某个页面,添加判断,是否是可以导航过去
NavigationParameters param = new NavigationParameters();
param.Add("value", "123");
_regionManager.RequestNavigate("ContentRegion", view,
new Action<NavigationResult>((result) =>
param);
return _viewACommand;
set { _viewACommand = value; }
第八种:判断能不能导航过去:IConfirmNavigationRequest
继承接口:IConfirmNavigationRequest
实现接口:ConfirmNavigationRequest
public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)
bool result = false;
if (MessageBox.Show("数据没保存,是否离开", "确认", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
// 允许导航
result = true;
// 不允许导航过来
continuationCallback(result);
完整示例:
<Window x:Class="YuTang.PrismLesson.Views.NavigationWindow"
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:YuTang.PrismLesson.Views"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d"
Title="NavigationWindow" Height="450" Width="800">
<Window.Resources>
<Style TargetType="TabItem">
<Setter Property="Header" Value="{Binding DataContext.Title}"/>
</Style>
</Window.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<Button Content="ViewA" Command="{Binding ViewACommand}" CommandParameter="ViewA"/>
<Button Content="ViewB" Command="{Binding ViewBCommand}"/>
<Button Content="Forword" Command="{Binding BackCommand}"/>
<Button Content="Back" Command="{Binding ForwordCommand}"/>
</StackPanel>
<ContentControl prism:RegionManager.RegionName="ContentRegion" Grid.Row="1"/>
<!--<TabControl prism:RegionManager.RegionName="ContentRegion" Grid.Row="1"/>-->
</Grid>
</Window>
public partial class App : PrismApplication
protected override Window CreateShell()
return Container.Resolve<NavigationWindow>();
protected override void RegisterTypes(IContainerRegistry containerRegistry)
containerRegistry.RegisterForNavigation<ViewA>();
containerRegistry.RegisterForNavigation<ViewB>();
ViewModel
public class NavigationWindowViewModel : BindableBase
IRegionManager _regionManager;
IRegionNavigationService _regionNavigationService;
public NavigationWindowViewModel(IRegionManager regionManager, IRegionNavigationService regionNavigationService)
_regionManager = regionManager;
_regionNavigationService = regionNavigationService;
private DelegateCommand<string> _viewACommand;
public DelegateCommand<string> ViewACommand
if (_viewACommand == null)
_viewACommand = new DelegateCommand<string>((view) =>
// 导航到 ViewA
// 传值
// 导航某个页面,添加判断,是否是可以导航过去
NavigationParameters param = new NavigationParameters();
param.Add("value", "123");
_regionManager.RequestNavigate("ContentRegion", view,
new Action<NavigationResult>((result) =>
param);
return _viewACommand;
set { _viewACommand = value; }
private DelegateCommand _viewBCommand;
public DelegateCommand ViewBCommand
if (_viewBCommand == null)
_viewBCommand = new DelegateCommand(() =>
// 导航到 ViewB
_regionManager.RequestNavigate("ContentRegion", "ViewB");
return _viewBCommand;
set { _viewBCommand = value; }
private DelegateCommand _forwordCommand;
public DelegateCommand ForwordCommand
if (_forwordCommand == null)
_forwordCommand = new DelegateCommand(() =>
//if (_regionNavigationJournal.CanGoForward)
// _regionNavigationJournal.GoForward();
var j = _regionManager.Regions["ContentRegion"].NavigationService.Journal;
//var j = _regionNavigationService.Journal;
if (j.CanGoForward)
j.GoForward();
return _forwordCommand;
set { _forwordCommand = value; }
private DelegateCommand _backCommand;
public DelegateCommand BackCommand
if (_backCommand == null)
_backCommand = new DelegateCommand(() =>
//var j = _regionNavigationService.Journal;
var j = _regionManager.Regions["ContentRegion"].NavigationService.Journal;
if (j.CanGoBack)
j.GoBack();
return _backCommand;
set { _backCommand = value; }
需要导航的内容
ViewA.XAML
<TextBlock Text="ViewA" FontSize="30"/>
<Button Content="Back" Command="{Binding GoBackCommand}" Height="40" Width="120"/>
</Grid>
ViewAViewModel.cs
public class ViewAViewModel : BindableBase, IActiveAware, INavigationAware, IConfirmNavigationRequest
IRegionNavigationJournal _journal;
public ViewAViewModel()
this.Title = "VIewA";
GoBackCommand = new DelegateCommand(GoBack);
private void GoBack()
_journal.GoBack();
private string _title;
public string Title
get { return _title; }
set { SetProperty(ref _title, value); }
public DelegateCommand GoBackCommand { get; set; }
// ===================================================IActiveAware
private bool _isActive;
public bool IsActive
get => _isActive;
_isActive = value;
if (value)
System.Diagnostics.Debug.WriteLine("ViewA 激活了");
System.Diagnostics.Debug.WriteLine("ViewA 失效了");
IsActiveChanged?.Invoke(this, new EventArgs());
public event EventHandler IsActiveChanged;
/// <summary>
/// =====================================================================INavigationAware========
/// </summary>
/// <param name="navigationContext"></param>
public void OnNavigatedTo(NavigationContext navigationContext)
// 导航传值
var param = navigationContext.Parameters["value"];
// 历史记录
_journal = navigationContext.NavigationService.Journal;
//_journal.GoForward();
//_journal.GoBack();
public bool IsNavigationTarget(NavigationContext navigationContext)
// 控件View是重现(返回True)还是新建(返回False)
return true;
public void OnNavigatedFrom(NavigationContext navigationContext)
// navigationContext可以拿ViewA和ViewB两个对象
// 触发时机
// ========================================================================IConfirmNavigationRequest
public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)
bool result = false;
if (MessageBox.Show("数据没保存,是否离开", "确认", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
// 允许导航
result = true;
// 不允许导航过来
continuationCallback(result);
Model
Model其实是一系列View的集合,是PrismApplication的扩展延伸。
是资源管理的延伸(继承IModule实现的两个方法很好的体现出来),一个程序集里View的注册,有了Module,可以由Module分别进行View的注册,Module再在PrismApplication里进行注册。
Model中创建View
Model中创建一个Module的管理类,负责注册:MainModule
继承:IModule实现两个接口
OnInitialized
RegisterTypes
public class MainModule : IModule
public void OnInitialized(IContainerProvider containerProvider)
var region = containerProvider.Resolve<IRegionManager>();
//Region
region.RegisterViewWithRegion("LeftDockRegion", typeof(LeftMenuView));
region.RegisterViewWithRegion("TopDockRegion", typeof(HeaderView));
//containerProvider.Resolve<IContainerExtension>().Register<ILeftMenuModel, LeftMenuModel>();
public void RegisterTypes(IContainerRegistry containerRegistry)
注册与发现
配置文件注册
配合App.config注册Module
App.config,配置文件注册与发现Model**
添加configSections节点:碰到module节点,就会实例化Prism.Modularity.ModulesConfigurationSection,然后把module加载出来。
添加modules节点
添加module节点
assemblyFile:程序集名
moduleType:通过Type进行反射,程序集全名称+程序集名称
moduleName:Module名
startupLoaded:加载的时机
fals 按需加载,需要了再加载
<configuration>
<configSections>
<section name="modules" type="Prism.Modularity.ModulesConfigurationSection, Prism.Wpf"/>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
<modules>
<module assemblyFile="YuTang.PrismLesson.MainModule.dll"
moduleType="YuTang.PrismLesson.MainModule.MainModule, YuTang.PrismLesson.MainModule"
moduleName="MainModule"
startupLoaded="True"/>
</modules>
</configuration>
App.xaml.cs中重写ConfigureModuleCatalog
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
base.ConfigureModuleCatalog(moduleCatalog);
moduleCatalog.AddModule<MainModule.MainModule>();
moduleCatalog.AddModule<SysModule.SysModule>();
重新生成Module程序集,并把dll文件复制到Shell主程序文件目录下。
配合Xml文件注册Moddule
增加一个ModuleConfig.xml文件
<?xml version="1.0" encoding="utf-8" ?>
<m:ModuleCatalog xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:m="clr-namespace:Prism.Modularity;assembly=Prism.Wpf">
<m:ModuleInfo ModuleName="MainModule"
ModuleType="YuTang.PrismLesson.MainModule.MainModule, YuTang.PrismLesson.MainModule, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</m:ModuleCatalog>
需要注意App.xaml.cs中的CreateModuleCatalog返回值需要重新写
protected override IModuleCatalog CreateModuleCatalog()
return new XamlModuleCatalog("ModuleConfig.xml");
代码基础注册
添加module引用
App.xaml.cs中ConfigureModuleCatalog注册
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
base.ConfigureModuleCatalog(moduleCatalog);
moduleCatalog.AddModule<MainModule.MainModule>();
代码按需加载
添加module引用
App.xaml.cs中ConfigureModuleCatalog注册
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
base.ConfigureModuleCatalog(moduleCatalog);
moduleCatalog.AddModule(new ModuleInfo
ModuleName = "MainModule",
ModuleType = typeof(MainModule.MainModule).AssemblyQualifiedName,
//加载时机 是否按需加载
InitializationMode = InitializationMode.OnDemand
代码IModuleManager任意对象中进行处理
添加module引用
App.xaml.cs中ConfigureModuleCatalog注册
还有一个Module加载完成的事件
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
base.ConfigureModuleCatalog(moduleCatalog);
// 任意对象中进行处理,通过对象的构造函数注入ModuleManager的实例
IModuleManager moduleManager = null;
moduleManager.LoadModule<MainModule.MainModule>();
moduleManager.LoadModuleCompleted += (se, ev) => { };
自动扫描目录注册
手动把Module生成的dll,移动到指定目录
通过程序集=》属性=》生成=》配置生成路径指定
通过程序集=》属性=》生成事件=》配置生成路径
定义Module,通过特性控制是否按需加载
[Module(ModuleName = "MainModule", OnDemand = false)]
public class MainModule : IModule
public void OnInitialized(IContainerProvider containerProvider)
var region = containerProvider.Resolve<IRegionManager>();
//Region
region.RegisterViewWithRegion("LeftDockRegion", typeof(LeftMenuView));
public void RegisterTypes(IContainerRegistry containerRegistry)
bin.debug中添加目录Modules
把module生成的dll,放到目录中
App.xaml.cs中ConfigureModuleCatalog注册
protected override IModuleCatalog CreateModuleCatalog()
// 扫描目录
return new DirectoryModuleCatalog() { ModulePath = @".\Modules" };
Dialog弹出窗口
添加一个用户控件(作为弹出窗口的内容)
Module类中注册Dialog弹出窗口
public class SysModule : IModule
public void OnInitialized(IContainerProvider containerProvider){ }
public void RegisterTypes(IContainerRegistry containerRegistry)
containerRegistry.RegisterDialog<UserEditView>();
实现对应的ViewModel,并实现IDialogAware接口
public class UserEditViewModel : IDialogAware
public string Title => "用户信息编辑";
public event Action<IDialogResult> RequestClose;
//是否可以关闭
public bool CanCloseDialog()
return true;
public void OnDialogClosed()
public void OnDialogOpened(IDialogParameters parameters)
构造函数注入:IDialogService,
包括Show、ShowDialog
第二个参数可以给弹出窗口传参
回调,是窗口状态(在弹出窗口的ViewModel中处理才可以)
创建打开命令,通过注入的IDialogService方法ShowDialog打开弹窗
public DelegateCommand OpenDialogCommand { get; private set; }
OpenDialogCommand = new DelegateCommand(() =>
DialogParameters param = new DialogParameters();
// View的注册名称 - 参数键值对 - 弹窗回调 - 指定弹出窗口的注册名称
dialogService.ShowDialog("UserEditView", param,
(result) =>
自定义弹窗传参
创建自定义控件弹窗
实现自定义控件的ViewModel,继承IDialogAware
app.cs注入弹窗
ViewModel中调用弹窗
<UserControl x:Class="PrismBlankCoreApp.Views.DialogUC"
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:PrismBlankCoreApp.Views"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d"
d:DesignHeight="450"
d:DesignWidth="800">
<StackPanel>
<TextBox Height="30"
Width="200"
Background="Orange"
Text="{Binding PropertyName}" />
<Button Content="确定"
Command="{Binding OkCommand}" />
<Button Content="取消"
Command="{Binding CancelCommand}" />
</StackPanel>
</UserControl>
ViewModel
namespace PrismBlankCoreApp.ViewModels
public class DialogUCViewModel : BindableBase, IDialogAware
public string Title => "传参弹窗测试";
public event Action<IDialogResult> RequestClose;
public bool CanCloseDialog()
return true;
public void OnDialogClosed()
//关闭触发
public void OnDialogOpened(IDialogParameters parameters)
//打开时触发
private string fieldName;
public string PropertyName
get { return fieldName; }
set { SetProperty(ref fieldName, value); }
private DelegateCommand _okCommand;
public DelegateCommand OkCommand =>
_okCommand ?? (_okCommand = new DelegateCommand(ExecuteOkCommand));
private void ExecuteOkCommand()
var result = ButtonResult.OK;
DialogParameters parameters = new DialogParameters();
parameters.Add("参数名", PropertyName);
RequestClose?.Invoke(new DialogResult(result, parameters));
catch (Exception ex)
Console.WriteLine(ex.Message);
throw;
private DelegateCommand _cancelCommand;
public DelegateCommand CancelCommand =>
_cancelCommand ?? (_cancelCommand = new DelegateCommand(ExecuteCancelCommand));
private void ExecuteCancelCommand()
RequestClose?.Invoke(new DialogResult(ButtonResult.No));
public partial class App
protected override Window CreateShell()
return Container.Resolve<MainWindow>();
protected override void RegisterTypes(IContainerRegistry containerRegistry)
containerRegistry.RegisterDialog<DialogUC>();
public class MainWindowViewModel : BindableBase
private readonly IDialogService _dialogService;
private string _title = "Prism Application";
public string Title
get { return _title; }
set { SetProperty(ref _title, value); }
private string fieldName;
public string PropertyName
get { return fieldName; }
set { SetProperty(ref fieldName, value); }
private DelegateCommand _dialogCommand;
public DelegateCommand DialogCommand =>
_dialogCommand ?? (_dialogCommand = new DelegateCommand(ExecuteDialogCommand));
private void ExecuteDialogCommand()
DialogParameters param = new DialogParameters();
_dialogService.ShowDialog("DialogUC", param, (result) =>
if (result.Result == ButtonResult.OK)
string str = result.Parameters.GetValue<string>("参数名");
PropertyName = str;
catch (System.Exception ex)
System.Console.WriteLine(ex.Message);
public MainWindowViewModel(IDialogService dialogService)
_dialogService = dialogService;
改变弹窗样式
通过prism:Dialog.WindowStyle修改弹窗样式,比较少用,一般使用的是自定义弹窗。
<prism:Dialog.WindowStyle>
<Style TargetType="Window">
<Setter Property="WindowStyle" Value="None"/>
<Setter Property="Width" Value="500"/>
<Setter Property="Height" Value="300"/>
<Setter Property="SizeToContent" Value="Manual"/>
</Style>
</prism:Dialog.WindowStyle>
<TextBlock Text="UserEdit" FontSize="30"/>
</Grid>
自定义弹窗
多个程序或地方使用,创建一个程序集。
添加一个窗口
xaml文件中只处理样式
.cs文件中继承接口IDialogWindow
public partial class DialogWindow : Window, IDialogWindow
public DialogWindow()
InitializeComponent();
public IDialogResult Result { get; set; }
在App.xaml.cs中注册
protected override void RegisterTypes(IContainerRegistry containerRegistry)
containerRegistry.RegisterDialogWindow<DialogWindow>();
//containerRegistry.RegisterDialogWindow<DialogWindow>("DialogWindow");
OpenDialogCommand = new DelegateCommand(() =>
DialogParameters param = new DialogParameters();
// View的注册名称 - 参数键值对 - 弹窗回调 - 指定弹出窗口的注册名称
dialogService.ShowDialog("UserEditView", param,
(result) =>
TabControl示例
实现一个TabControl,带关闭按钮。
<Window.Resources>
<Style TargetType="Button" x:Key="TabCloseButtonStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border VerticalAlignment="Center" HorizontalAlignment="Center" CornerRadius="3" Background="Transparent"
Name="back">
<Path Data="M0 0 8 8M0 8 8 0" Margin="5"
Stroke="{TemplateBinding Foreground}" StrokeThickness="1"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#19000000" TargetName="back"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="TabItem">
<Setter Property="Header" Value="{Binding DataContext.Title}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Margin" Value="2,0"/>
<Setter Property="Foreground" Value="#444"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabItem">
<Grid Background="{TemplateBinding Background}" Height="30">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{TemplateBinding Header}" VerticalAlignment="Center" Margin="10,5,5,5"/>
<Button Grid.Column="1" Style="{StaticResource TabCloseButtonStyle}" Foreground="{TemplateBinding Foreground}"
Visibility="Collapsed" Name="close_btn"
Command="{Binding DataContext.CloseCommand}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Visibility" Value="Visible" TargetName="close_btn"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Visibility" Value="Visible" TargetName="close_btn"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#EEE"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="orange"/>
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<DockPanel>
<ContentControl DockPanel.Dock="Left" Width="220" prism:RegionManager.RegionName="LeftDockRegion"/>
<ContentControl DockPanel.Dock="Top" Height="80" prism:RegionManager.RegionName="TopDockRegion"/>
<TabControl prism:RegionManager.RegionName="ContentRegion"/>
</DockPanel>
</Grid>
public class MenuManagementViewModel : BindableBase, INavigationAware
private string UriPath = "";
private string _title;
public string Title
get { return _title; }
set { _title = value; }
public DelegateCommand<string> CloseCommand { get; private set; }
public DelegateCommand SaveCommand { get; private set; }
public MenuManagementViewModel(IRegionManager regionManager, IUnityContainer unityContainer, ICompositeCommands compositeCommands)
this.Title = "菜单管理";
CloseCommand = new DelegateCommand<string>((param) =>
// 把所在Region里面的当前ViewModel对应的View移除掉
// 操作Region
// 通过Unity顶层容器获取对应的类型
var obj = unityContainer.Registrations.Where(v => v.Name == UriPath).FirstOrDefault();
string name = obj.MappedToType.Name;
if (!string.IsNullOrEmpty(name))
var region = regionManager.Regions["ContentRegion"];
var view = region.Views.Where(v => v.GetType().Name == UriPath).FirstOrDefault();
if (view != null)
region.Remove(view);
SaveCommand = new DelegateCommand(() =>
// 菜单保存
compositeCommands.DoCommand.RegisterCommand(SaveCommand);
public void OnNavigatedTo(NavigationContext navigationContext)
UriPath = navigationContext.Uri.ToString();
public bool IsNavigationTarget(NavigationContext navigationContext)
return true;
public void OnNavigatedFrom(NavigationContext navigationContext)
public class SysModule : IModule
public void OnInitialized(IContainerProvider containerProvider)
public void RegisterTypes(IContainerRegistry containerRegistry)
containerRegistry.RegisterForNavigation<MenuManagementView>("mmView");
containerRegistry.RegisterForNavigation<UserManagementView>();
containerRegistry.RegisterDialog<UserEditView>();