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看起来如下:

<ad:DockingManager Background="AliceBlue" x:Name="WorkspaceRegion" prism:RegionManager.RegionName="WorkspaceRegion">
                        <ad:LayoutRoot>
                            <ad:LayoutPanel>
                                <ad:LayoutDocumentPaneGroup>
                                    <ad:LayoutDocumentPane>

                                    </ad:LayoutDocumentPane>
                                </ad:LayoutDocumentPaneGroup>
                            </ad:LayoutPanel>
                        </ad:LayoutRoot>
                    </ad:DockingManager>

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

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

#region Constructor

        public AvalonDockRegionAdapter(IRegionBehaviorFactory factory)
            : base(factory)
        {
        }

        #endregion  //Constructor


        #region Overrides

        protected override IRegion CreateRegion()
        {
            return new AllActiveRegion();
        }

        protected override void Adapt(IRegion region,DockingManager regionTarget)
        {
            region.Views.CollectionChanged += delegate(
                Object sender,NotifyCollectionChangedEventArgs e)
                {
                    this.OnViewsCollectionChanged(sender,e,region,regionTarget);
                };

            regionTarget.DocumentClosed += delegate(
                            Object sender,DocumentClosedEventArgs e)
            {
                this.OnDocumentClosedEventArgs(sender,region);
            };
        }

        #endregion  //Overrides


        #region Event Handlers

        /// <summary>
        /// Handles the NotifyCollectionChangedEventArgs event.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The event.</param>
        /// <param name="region">The region.</param>
        /// <param name="regionTarget">The region target.</param>
        void OnViewsCollectionChanged(object sender,NotifyCollectionChangedEventArgs e,IRegion region,DockingManager regionTarget)
        {
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                foreach (FrameworkElement item in e.NewItems)
                {
                    UIElement view = item as UIElement;

                    if (view != null)
                    {
                        //Create a new layout document to be included in the LayoutDocuemntPane (defined in xaml)
                        LayoutDocument newLayoutDocument = new LayoutDocument();
                        //Set the content of the LayoutDocument
                        newLayoutDocument.Content = item;

                        viewmodelBase_2 viewmodel = (viewmodelBase_2)item.DataContext;

                        if (viewmodel != null)
                        {
                            //All my viewmodels have properties DisplayName and IconKey
                            newLayoutDocument.Title = viewmodel.DisplayName;
                            //GetImageUri is custom made method which gets the icon for the LayoutDocument
                            newLayoutDocument.IconSource = this.GetImageUri(viewmodel.IconKey);
                        }

                        //Store all LayoutDocuments already pertaining to the LayoutDocumentPane (defined in xaml)
                        List<LayoutDocument> oldLayoutDocuments = new List<LayoutDocument>();
                        //Get the current ILayoutDocumentPane ... Depending on the arrangement of the views this can be either 
                        //a simple LayoutDocumentPane or a LayoutDocumentPaneGroup
                        ILayoutDocumentPane currentILayoutDocumentPane = (ILayoutDocumentPane)regionTarget.Layout.RootPanel.Children[0];

                        if (currentILayoutDocumentPane.GetType() == typeof(LayoutDocumentPaneGroup))
                        {
                            //If the current ILayoutDocumentPane turns out to be a group
                            //Get the children (LayoutDocuments) of the first pane
                            LayoutDocumentPane oldLayoutDocumentPane = (LayoutDocumentPane)currentILayoutDocumentPane.Children.ToList()[0];
                            foreach (LayoutDocument child in oldLayoutDocumentPane.Children)
                            {
                                oldLayoutDocuments.Insert(0,child);
                            }
                        }
                        else if (currentILayoutDocumentPane.GetType() == typeof(LayoutDocumentPane))
                        {
                            //If the current ILayoutDocumentPane turns out to be a simple pane
                            //Get the children (LayoutDocuments) of the single existing pane.
                            foreach (LayoutDocument child in currentILayoutDocumentPane.Children)
                            {
                                oldLayoutDocuments.Insert(0,child);
                            }
                        }

                        //Create a new LayoutDocumentPane and inserts your new LayoutDocument
                        LayoutDocumentPane newLayoutDocumentPane = new LayoutDocumentPane();
                        newLayoutDocumentPane.InsertChildAt(0,newLayoutDocument);

                        //Append to the new LayoutDocumentPane the old LayoutDocuments
                        foreach (LayoutDocument doc in oldLayoutDocuments)
                        {
                            newLayoutDocumentPane.InsertChildAt(0,doc);
                        }

                        //Traverse the visual tree of the xaml and replace the LayoutDocumentPane (or LayoutDocumentPaneGroup) in xaml
                        //with your new LayoutDocumentPane (or LayoutDocumentPaneGroup)
                        if (currentILayoutDocumentPane.GetType() == typeof(LayoutDocumentPane))
                            regionTarget.Layout.RootPanel.ReplaceChildAt(0,newLayoutDocumentPane);
                        else if (currentILayoutDocumentPane.GetType() == typeof(LayoutDocumentPaneGroup))
                        {
                            currentILayoutDocumentPane.ReplaceChild(currentILayoutDocumentPane.Children.ToList()[0],newLayoutDocumentPane);
                            regionTarget.Layout.RootPanel.ReplaceChildAt(0,currentILayoutDocumentPane);
                        }
                        newLayoutDocument.IsActive = true;
                    }
                }
            }
        }

        /// <summary>
        /// Handles the DocumentClosedEventArgs event raised by the DockingNanager when
        /// one of the LayoutContent it hosts is closed.
        /// </summary>
        /// <param name="sender">The sender</param>
        /// <param name="e">The event.</param>
        /// <param name="region">The region.</param>
        void OnDocumentClosedEventArgs(object sender,DocumentClosedEventArgs e,IRegion region)
        {
            region.Remove(e.Document.Content);
        }

        #endregion  //Event handlers

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

protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
        {
            // Call base method
            var mappings = base.ConfigureRegionAdapterMappings();
            if (mappings == null) return null;

            // Add custom mappings
            mappings.RegisterMapping(typeof(DockingManager),ServiceLocator.Current.GetInstance<AvalonDockRegionAdapter>());

            // Set return value
            return mappings;
        }

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

健康长寿·繁荣昌盛!

猜你在找的C#相关文章