並不是所有控件都可以被用作Region了嗎?我們將Gird塊的代碼變成這樣:
<Grid>
<ContentControl prism:RegionManager.RegionName="ContentRegion" />
<StackPanel prism:RegionManager.RegionName="ContentRegion2" />
</Grid>
似乎看上去一切正常,讓我們來啟動他。
Oops!!!程序並沒有按照我們想象的那樣啟動,而是拋給了我們一個異常:
Prism.Regions.UpdateRegionsException: 'An exception occurred while trying to create region objects.
Prism在生成一個Region對象的時候報錯了,看上去,StackPanel並不支持用作Region。那么有其他的方法讓他可以被用作Region嗎?~~因為我們很喜歡用StackPanel啊( ﹁ ﹁ ) →(不要管我為什么喜歡,你不,我就偏要)~ 這難不倒Prism,畢竟創建Region對象就是他自己的事情,做分內的事應該沒問題的。
你需要為一個將被用作Region的添加RegionAdapter(適配器)。RegionAdapter的作用是為特定的控件創建相應的Region,並將控件與Region進行綁定,然后為Region添加一些行為。一個RegionAdapter需要實現IRegionAdapte接口,如果你需要自定義一個RegionAdapter,可以通過繼承RegionAdapterBase類來省去一些工作。
那,為什么ContentControl就可以呢?因為:
The Composite Application Library provides three region adapters out-of-the-box:
- ContentControlRegionAdapter. This adapter adapts controls of type System.Windows.Controls.ContentControl and derived classes.
- SelectorRegionAdapter. This adapter adapts controls derived from the class System.Windows.Controls.Primitives.Selector, such as the System.Windows.Controls.TabControl control.
- ItemsControlRegionAdapter. This adapter adapts controls of type System.Windows.Controls.ItemsControl and derived classes.
因為這三個是內定的(蛤蛤),就是已經幫你實現了RegionAdapter。接下來,我們看看怎么為StackPanel實現RegionAdapter。
- step1 新建一個類
StackPanelRegionAdapter.cs
,繼承RegionAdapterBase,這個類已經幫我們實現了IRegionAdapte接口。
using Prism.Regions;
using System.Windows;
using System.Windows.Controls;
namespace Regions.Prism
{
public class StackPanelRegionAdapter : RegionAdapterBase<StackPanel>
{
public StackPanelRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory)
: base(regionBehaviorFactory)
{
}
protected override void Adapt(IRegion region, StackPanel regionTarget)
{
region.Views.CollectionChanged += (s, e) =>
{
if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
{
foreach (FrameworkElement element in e.NewItems)
{
regionTarget.Children.Add(element);
}
}
//handle remove
};
}
protected override IRegion CreateRegion()
{
return new AllActiveRegion();
}
}
}
- setp2 在
App.xaml.cs
注冊綁定
[7.1updated]
protected override void ConfigureRegionAdapterMappings(RegionAdapterMappings regionAdapterMappings)
{
base.ConfigureRegionAdapterMappings(regionAdapterMappings);
regionAdapterMappings.RegisterMapping(typeof(StackPanel), Container.Resolve<StackPanelRegionAdapter>());
}
我們現在可以為StackPanel
實現用作Region了。我們再運行剛才拋給我們異常的程序,是不是已經跑起來了呢?