与棱镜地区适配器AvalonDock [英] AvalonDock with Prism Region Adapter

查看:571
本文介绍了与棱镜地区适配器AvalonDock的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看到的SO一些问题,但他们都不似乎适用于我。我希望能够利用巨大的 Avalondock 2.0 与棱镜4.然而,所有样品该区域适配器是Avalondock 1.x的系列,我不能得到它的工作。

I have seen some questions on SO but none of them seemed applicable for me. I want to be able to use the great Avalondock 2.0 with Prism 4. However, all the sample region adapters for that is for Avalondock 1.x series, that I cannot get it working.

有没有人对如何创建AvalonDock的LayoutDocumentPane区域适配器示例代码和LayoutAnchorablePane?

Does anyone have sample code on how to create a Region Adapter for AvalonDock's LayoutDocumentPane and LayoutAnchorablePane?

推荐答案

不幸的是,据我所知,无论是LayoutDocumentPane和LayoutAnchorablePane不允许包含/创作RegionAdapters的,但是DockingManager一样。一个解决办法是建立对于DockingManager ,然后这将管理的可视化树中的LayoutDocuments的实例化一个 RegionAdapter。

Unfortunately, to the best of my knowledge, both the "LayoutDocumentPane" and the "LayoutAnchorablePane" do not allow the inclusion/creation of RegionAdapters, however the "DockingManager" does. One solution would be to create a RegionAdapter for the DockingManager which would then manage the instantiation of "LayoutDocuments" within the visual tree.

在XAML将如下所示:

The xaml would look as follows:

<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将承载相关联的意见LayoutDocuments被添加到WorkspaceRegion

Note that the region is defined in the DockingManager tag and there exists a single LayoutDocumentPaneGroup under LayoutPanel. The LayoutDocumentPane under the LayoutDocumentPaneGroup will host the LayoutDocuments associated to the views to be added to the "WorkspaceRegion".

至于RegionAdapter本身参考下面我提供的代码带有说明性注释

As for the RegionAdapter itself refer to the code below which I provided with explanatory comments

#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, e, 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



不要忘记添加下面的代码在你的引导程序,这样棱镜知道你RegionAdapter的存在

Do not forget to add the code below in your Bootstrapper so that Prism is aware of the existence of your 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。

Voilà. I know this is not the cleanest of solutions but it should work. The same approach can easily be applied to "LayoutAnchorablePane".

很长很精彩!

这篇关于与棱镜地区适配器AvalonDock的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆