【问题标题】:A WPF docking library supporting MVVM一个支持 MVVM 的 WPF 对接库
【发布时间】:2011-11-21 02:03:08
【问题描述】:

我已经看到了this one之类的问题,但是我想使用的对接库必须有一个重要的特性,没有被问到:它必须支持MVVM。

那么,在 Telerik、DotNetBar、DevZest 和周围的其他库(不包括我已经测试过的 AvalonDock)中,您是否实际使用了 MVVM?

提前致谢

【问题讨论】:

  • AvalonDock 应该可以工作,我知道人们将它与 Caliburn Micro 一起使用。 goo.gl/gRVo5
  • @Derek Beattie:不,AvalonDock 不兼容 MVVM。为此我遇到了很多麻烦,不得不扩展组件。我会尽快写一篇关于它的博客文章,以便任何有需要的开发人员都可以使用它
  • 是的,我很好奇是什么让它不兼容 Mvvm,我从未使用过它。
  • @Mike,我也面临着类似的问题。有没有找到支持 MVVM 模型的库
  • @Chandermani 不。这个项目已经搁置了几个月。我很快就会有一些时间花在这上面。如果我能找到合适的解决方案,我会更新帖子

标签: wpf mvvm dock


【解决方案1】:

你好,迈克试试这个:

  1. 简单方法:实现Sofa, An adaptation of AvalonDock for Prism
  2. 使用 AvalonDock 并像这样实现自定义区域适配器:

    public class ResizingPanelRegionAdapter : RegionAdapterBase<DockingManager>
    {
    public ResizingPanelRegionAdapter(IRegionBehaviorFactory factory)
        : base(factory)
    {
    
    }
    protected override IRegion CreateRegion()
    {
        return new AllActiveRegion();
    }
    
    protected override void Adapt(IRegion region, DockingManager regionTarget)
    {
        region.Views.CollectionChanged += delegate(Object sender, NotifyCollectionChangedEventArgs e)
        {
            OnViewsCollectionChanged(sender, e, region, regionTarget);
        };
    }
    
    private void OnViewsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e, IRegion region, DockingManager regionTarget)
    {
        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            foreach (object item in e.NewItems)
            {
                UIElement view = item as UIElement;
                if (view != null)
                {
                    //Get 
                    ResizingPanel resizingPanel = GetResizingPanel(regionTarget.Content);
                    resizingPanel.Background = Brushes.White;
                    DocumentPane document = GetDocumentPane(resizingPanel.Children);
                    //document.Background = Brushes.White;
    
                    DocumentContent newContentPane = new DocumentContent();
                    newContentPane.Content = item;
                    var itemView = (item as IViewBase);
                    if (itemView != null)
                        newContentPane.Title = itemView.Title;
                    //When contentPane is closed remove the associated region
                    newContentPane.Closed += (contentPaneSender, args) =>
                    {
                        region.Remove(item);
                        newContentPane.Content = null;
                    };
    
                    document.Items.Add(newContentPane);
    
                    if (!resizingPanel.Children.Contains(document))
                        resizingPanel.Children.Add(document);
    
                    regionTarget.Content = resizingPanel;
    
                    newContentPane.Activate();
                    region.Activate(item);
                }
            }
        }
        else if (e.Action == NotifyCollectionChangedAction.Remove)
        {
    
        }
    }
    
    private DocumentPane GetDocumentPane(UIElementCollection collection)
    {
        foreach (object item in collection)
        {
            var documentPanel = item as DocumentPane;
            if (documentPanel != null)
                return documentPanel;
        }
        return new DocumentPane();
    }
    
    private ResizingPanel GetResizingPanel(object content)
    {
        var resizingPanel = content as ResizingPanel;
        if (resizingPanel != null)
            return resizingPanel;
        return new ResizingPanel();
    }    
    }
    

你可以在你的 XAML 中这样实现它:

<avalon:DockingManager prism:RegionManager.RegionName="MainRegion">
</avalon:DockingManager>

它是如何工作的? 很简单,首先你要记住Region adapters are responsible for creating a region and associating it with the control. This allows you to use the IRegion interface to manage the UI control contents in a consistent way.

还有一个DockingManager is the core control in AvalonDock. It arranges contained panes, handles fly out panes and floating windows.

因此,按照这个示例,您可以为 avalon 实现一个自定义区域适配器,我在一个项目中使用此实现获得了非常好的结果。

问候

【讨论】:

  • 感谢您的回答。不幸的是,我使用 CaliburnMicro 而不是 Prism。我去看看沙发,看看能不能找到解决办法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-21
  • 1970-01-01
  • 2010-12-07
  • 2010-09-26
  • 2011-06-03
  • 2018-08-24
  • 2010-11-12
相关资源
最近更新 更多