Region定义
1、Xaml方式注册一个区域
<ContentControl x:Name="cc" prism:RegionManager.RegionName="ContentRegion"/>
2、后台代码注册一个区域
public MainWindow(IRegionManager regionManager)
{
InitializeComponent();
RegionManager.SetRegionName(this.cc, "ContentRegion");
/// 将相关View指定到特定的Region
/// 第一个参数:Region的名称
/// 第二个参数:View的类型
regionManager.RegisterViewWithRegion("ContentRegion", typeof(ViewA));
}
RegionAdapter介绍
Prism框架中内置的RegionAdapter:
- ContentControl——对应ContentControlRegionAdapter
- ItemsControl——对应ItemsControlRegionAdapter
- ListView、ListBox、ComboBox——对应SelectorRegionAdapter
- TabControl——TabControlRegionAdapter
其他的容器或者控件,需自定义RegionAdapter(继承RegionAdapterBase< T >),并在App.cs类中注册。
1、自定义的StackPanelRegionAdapter如下:
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();
}
2、在App类中ConfigureRegionAdapterMappings方法中关联RegionAdapter
protected override void ConfigureRegionAdapterMappings(RegionAdapterMappings regionAdapterMappings)
{
base.ConfigureRegionAdapterMappings(regionAdapterMappings);
regionAdapterMappings.RegisterMapping<StackPanel>(Container.Resolve<StackPanelRegionAdapter>());
}
RegionContext介绍
RegionManager.RegionContext为数据上下文的绑定,与DataContext类似;适用于Region处的UI形式不变,而数据刷新的场景(根据RegionContext绑定不同的对象,切换不同的数据源)
<ContentControl prism:RegionManager.RegionName="ContentRegion" prism:RegionManager.RegionContext="{Binding xxx}"/>
Region视图切换
通过Activate和Deactivate来实现
// 获取Region对象
var _region = _regionManager.Regions["ContentRegion"];
_region.Activate(_containerExtension.Resolve<ViewB>());
_region.Deactivate(_containerExtension.Resolve<ViewA>());
这种方法的前提是注入的View视图要为单例,如下:
this.Loaded += (se, ev) =>
{
var _region = _regionManager.Regions["ContentRegion"];
_containerExtension.RegisterSingleton<ViewA>();
_containerExtension.RegisterSingleton<ViewB>();
_region.Add(_containerExtension.Resolve<ViewA>());
_region.Add(_containerExtension.Resolve<ViewB>());
};
另外,Activate和Deactivate有针对,并不是所有Adapter适用,对ContentControlRegionAdapter支持,而ItemsControlRegionAdapter使用会报错。
其实,视图切换更推荐采用Navigation的方式
IActiveAware
View视图对应ViewModel继承IActiveAware接口,可捕获View视图是否被激活了
public class ViewAViewModel : BindableBase, IActiveAware
{
// ===================================================IActiveAware
private bool _isActive;
public bool IsActive
{
get => _isActive;
set
{
_isActive = value;
if (value)
{
System.Diagnostics.Debug.WriteLine("ViewA 激活了");
}
else
{
System.Diagnostics.Debug.WriteLine("ViewA 失效了");
}
IsActiveChanged?.Invoke(this, new EventArgs());
}
}
public event EventHandler IsActiveChanged;
}