我使用Prism 6.我有(AvalonDock)RegionAdapter
的自定义LayoutDocumentPane
。我这样使用它:
<!-- relevant lines from Shell.xaml. These regions are autoWired -->
<ad:LayoutDocumentPaneGroup>
<ad:LayoutDocumentPane prism:RegionManager.RegionName="{x:Static inf:RegionNames.ContentRegion}">
</ad:LayoutDocumentPane>
</ad:LayoutDocumentPaneGroup>
...
<ContentControl prism:RegionManager.RegionName={x:Static inf:RegionNames.TestRegion}">
...
My RegionAdapter:
public class AvalonDockLayoutDocumentRegionAdapter : RegionAdapterBase<LayoutDocumentPane>
{
public AvalonDockLayoutDocumentRegionAdapter(IRegionBehaviorFactory factory) : base(factory)
{
}
protected override void Adapt(IRegion region, LayoutDocumentPane regionTarget)
{
region.Views.CollectionChanged += (sender, e) =>
{
OnRegionViewsCollectionChanged(sender, e, region, regionTarget);
};
}
private void OnRegionViewsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e, IRegion region, LayoutDocumentPane regionTarget)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
foreach (var item in e.NewItems)
{
var view = item as FrameworkElement;
if (view != null)
{
var layoutDocument = new LayoutDocument();
layoutDocument.Content = view;
var vm = view.DataContext as ILayoutPaneAware;
if (vm != null)
{
//todo bind to vm.Title instead
layoutDocument.Title = vm.Title;
}
regionTarget.Children.Add(layoutDocument);
layoutDocument.IsActive = true;
}
}
} else if (e.Action == NotifyCollectionChangedAction.Remove)
{
foreach (var item in e.OldItems)
{
var frameworkElement = item as FrameworkElement;
var childToRemove = frameworkElement.Parent as ILayoutElement;
regionTarget.RemoveChild(childToRemove);
}
}
}
protected override IRegion CreateRegion()
{
return new Region();
}
}
当然我用Bootstrapper注册它
...
protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
{
var mappings = base.ConfigureRegionAdapterMappings();
mappings.RegisterMapping(typeof(LayoutDocumentPane), Container.Resolve<AvalonDockLayoutDocumentRegionAdapter>());
return mappings;
}
protected override void InitializeShell()
{
var regionManager = RegionManager.GetRegionManager(Shell);
// Here, regionManager.Regions only contains 1 Region - "TestRegion".
// Where is my region from the custom RegionAdapter?
Application.Current.MainWindow.Show();
}
protected override DependencyObject CreateShell()
{
return Container.Resolve<Shell>();
}
protected override void ConfigureModuleCatalog()
{
ModuleCatalog moduleCatalog = (ModuleCatalog)ModuleCatalog;
moduleCatalog.AddModule(typeof(HelloWorldModule.HelloWorldModule));
}
...
我的模块
...
public HelloWorldModule(IRegionManager regionManager, IUnityContainer container)
{
_regionManager = regionManager;
_container = container;
}
public void Initialize()
{
_container.RegisterTypeForNavigation<HelloWorldView>("HelloWorldView");
// When uncommented, this next line works even though the region
// with this name doesn't appear in the list of regions in _regionManager
//_regionManager.RegisterViewWithRegion(RegionNames.ContentRegion, typeof(HelloWorldView));
}
...
现在,请参阅Bootstrapper.InitializeShell
来电和HelloWorldModule.Initialize
来电,RegionManager
- &#34; TestRegion&#34;中只有1个区域。如果我registerViewWithRegion
到我的&#34; ContentRegion&#34;它在该区域中放置了一个视图实例,即使它没有在区域中列出。
如果我尝试从ShellViewModel
中的ICommand函数导航(例如按下按钮),我可以导航到TestRegion
但不是ContentRegion
中的内容。我似乎无法导航到我的自定义RegionAdapter
创建的任何区域。我错过了什么?
答案 0 :(得分:0)
下面的代码很可能会导致问题。
protected override IRegion CreateRegion()
{
return new Region();
}
尝试更改以返回可以托管多个有效视图的区域
protected override IRegion CreateRegion()
{
return new AllActiveRegion();
}
答案 1 :(得分:0)
我在GitHub上的your issue中看到了这一点。
根据控件的创建方式,您可能需要通过以下方式自行设置控件上的棱镜RegionManager
:
private readonly IRegionManager _regionManager;
public AvalonDockLayoutDocumentRegionAdapter(
IRegionBehaviorFactory regionBehaviorFactory,
IRegionManager regionManager
) : base( regionBehaviorFactory ) {
this._regionManager = regionManager;
}
protected override void Adapt( IRegion region, LayoutDocumentPane target ) {
RegionManager.SetRegionManager( target, this._regionManager );
// continue with Adapt
}