c# – 带有棱镜区域适配器的AvalonDock

前端之家收集整理的这篇文章主要介绍了c# – 带有棱镜区域适配器的AvalonDock前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我已经看到了一些关于SO的问题,但它们似乎都不适用于我.我希望能够使用带有Prism 4的伟大的 Avalondock 2.0.但是,所有的样本区域适配器都是针对Avalondock 1.x系列,我无法让它工作.

有没有人有关于如何为AvalonDock的LayoutDocumentPane和LayoutAnchorablePane创建Region Adapter的示例代码

解决方法

不幸的是,据我所知,“LayoutDocumentPane”和“LayoutAnchorablePane”都不允许包含/创建RegionAdapters,但是“DockingManager”会这样做.一种解决方案是为DockingManager创建RegionAdapter,然后管理可视树中“LayoutDocuments”的实例化.

xaml看起来如下:

  1. <ad:DockingManager Background="AliceBlue" x:Name="WorkspaceRegion" prism:RegionManager.RegionName="WorkspaceRegion">
  2. <ad:LayoutRoot>
  3. <ad:LayoutPanel>
  4. <ad:LayoutDocumentPaneGroup>
  5. <ad:LayoutDocumentPane>
  6.  
  7. </ad:LayoutDocumentPane>
  8. </ad:LayoutDocumentPaneGroup>
  9. </ad:LayoutPanel>
  10. </ad:LayoutRoot>
  11. </ad:DockingManager>

请注意,该区域在DockingManager标记中定义,并且LayoutPanel下存在一个LayoutDocumentPaneGroup. LayoutDocumentPaneGroup下的LayoutDocumentPane将托管与要添加到“WorkspaceRegion”的视图关联的LayoutDocuments.

至于RegionAdapter本身,请参考下面的代码,我提供了解释性注释

  1. #region Constructor
  2.  
  3. public AvalonDockRegionAdapter(IRegionBehaviorFactory factory)
  4. : base(factory)
  5. {
  6. }
  7.  
  8. #endregion //Constructor
  9.  
  10.  
  11. #region Overrides
  12.  
  13. protected override IRegion CreateRegion()
  14. {
  15. return new AllActiveRegion();
  16. }
  17.  
  18. protected override void Adapt(IRegion region,DockingManager regionTarget)
  19. {
  20. region.Views.CollectionChanged += delegate(
  21. Object sender,NotifyCollectionChangedEventArgs e)
  22. {
  23. this.OnViewsCollectionChanged(sender,e,region,regionTarget);
  24. };
  25.  
  26. regionTarget.DocumentClosed += delegate(
  27. Object sender,DocumentClosedEventArgs e)
  28. {
  29. this.OnDocumentClosedEventArgs(sender,region);
  30. };
  31. }
  32.  
  33. #endregion //Overrides
  34.  
  35.  
  36. #region Event Handlers
  37.  
  38. /// <summary>
  39. /// Handles the NotifyCollectionChangedEventArgs event.
  40. /// </summary>
  41. /// <param name="sender">The sender.</param>
  42. /// <param name="e">The event.</param>
  43. /// <param name="region">The region.</param>
  44. /// <param name="regionTarget">The region target.</param>
  45. void OnViewsCollectionChanged(object sender,NotifyCollectionChangedEventArgs e,IRegion region,DockingManager regionTarget)
  46. {
  47. if (e.Action == NotifyCollectionChangedAction.Add)
  48. {
  49. foreach (FrameworkElement item in e.NewItems)
  50. {
  51. UIElement view = item as UIElement;
  52.  
  53. if (view != null)
  54. {
  55. //Create a new layout document to be included in the LayoutDocuemntPane (defined in xaml)
  56. LayoutDocument newLayoutDocument = new LayoutDocument();
  57. //Set the content of the LayoutDocument
  58. newLayoutDocument.Content = item;
  59.  
  60. viewmodelBase_2 viewmodel = (viewmodelBase_2)item.DataContext;
  61.  
  62. if (viewmodel != null)
  63. {
  64. //All my viewmodels have properties DisplayName and IconKey
  65. newLayoutDocument.Title = viewmodel.DisplayName;
  66. //GetImageUri is custom made method which gets the icon for the LayoutDocument
  67. newLayoutDocument.IconSource = this.GetImageUri(viewmodel.IconKey);
  68. }
  69.  
  70. //Store all LayoutDocuments already pertaining to the LayoutDocumentPane (defined in xaml)
  71. List<LayoutDocument> oldLayoutDocuments = new List<LayoutDocument>();
  72. //Get the current ILayoutDocumentPane ... Depending on the arrangement of the views this can be either
  73. //a simple LayoutDocumentPane or a LayoutDocumentPaneGroup
  74. ILayoutDocumentPane currentILayoutDocumentPane = (ILayoutDocumentPane)regionTarget.Layout.RootPanel.Children[0];
  75.  
  76. if (currentILayoutDocumentPane.GetType() == typeof(LayoutDocumentPaneGroup))
  77. {
  78. //If the current ILayoutDocumentPane turns out to be a group
  79. //Get the children (LayoutDocuments) of the first pane
  80. LayoutDocumentPane oldLayoutDocumentPane = (LayoutDocumentPane)currentILayoutDocumentPane.Children.ToList()[0];
  81. foreach (LayoutDocument child in oldLayoutDocumentPane.Children)
  82. {
  83. oldLayoutDocuments.Insert(0,child);
  84. }
  85. }
  86. else if (currentILayoutDocumentPane.GetType() == typeof(LayoutDocumentPane))
  87. {
  88. //If the current ILayoutDocumentPane turns out to be a simple pane
  89. //Get the children (LayoutDocuments) of the single existing pane.
  90. foreach (LayoutDocument child in currentILayoutDocumentPane.Children)
  91. {
  92. oldLayoutDocuments.Insert(0,child);
  93. }
  94. }
  95.  
  96. //Create a new LayoutDocumentPane and inserts your new LayoutDocument
  97. LayoutDocumentPane newLayoutDocumentPane = new LayoutDocumentPane();
  98. newLayoutDocumentPane.InsertChildAt(0,newLayoutDocument);
  99.  
  100. //Append to the new LayoutDocumentPane the old LayoutDocuments
  101. foreach (LayoutDocument doc in oldLayoutDocuments)
  102. {
  103. newLayoutDocumentPane.InsertChildAt(0,doc);
  104. }
  105.  
  106. //Traverse the visual tree of the xaml and replace the LayoutDocumentPane (or LayoutDocumentPaneGroup) in xaml
  107. //with your new LayoutDocumentPane (or LayoutDocumentPaneGroup)
  108. if (currentILayoutDocumentPane.GetType() == typeof(LayoutDocumentPane))
  109. regionTarget.Layout.RootPanel.ReplaceChildAt(0,newLayoutDocumentPane);
  110. else if (currentILayoutDocumentPane.GetType() == typeof(LayoutDocumentPaneGroup))
  111. {
  112. currentILayoutDocumentPane.ReplaceChild(currentILayoutDocumentPane.Children.ToList()[0],newLayoutDocumentPane);
  113. regionTarget.Layout.RootPanel.ReplaceChildAt(0,currentILayoutDocumentPane);
  114. }
  115. newLayoutDocument.IsActive = true;
  116. }
  117. }
  118. }
  119. }
  120.  
  121. /// <summary>
  122. /// Handles the DocumentClosedEventArgs event raised by the DockingNanager when
  123. /// one of the LayoutContent it hosts is closed.
  124. /// </summary>
  125. /// <param name="sender">The sender</param>
  126. /// <param name="e">The event.</param>
  127. /// <param name="region">The region.</param>
  128. void OnDocumentClosedEventArgs(object sender,DocumentClosedEventArgs e,IRegion region)
  129. {
  130. region.Remove(e.Document.Content);
  131. }
  132.  
  133. #endregion //Event handlers

不要忘记在Bootstrapper中添加以下代码,以便Prism知道RegionAdapter的存在

  1. protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
  2. {
  3. // Call base method
  4. var mappings = base.ConfigureRegionAdapterMappings();
  5. if (mappings == null) return null;
  6.  
  7. // Add custom mappings
  8. mappings.RegisterMapping(typeof(DockingManager),ServiceLocator.Current.GetInstance<AvalonDockRegionAdapter>());
  9.  
  10. // Set return value
  11. return mappings;
  12. }

瞧.我知道这不是最干净的解决方案,但应该有效.同样的方法可以很容易地应用于“LayoutAnchorablePane”.

健康长寿·繁荣昌盛!

猜你在找的C#相关文章