AvalonDock MVVM固定位置

时间:2019-05-08 13:14:43

标签: c# wpf xaml mvvm avalondock

我的MVVM WPF应用程序中有一个AvalonDock(版本3.5)。绑定如下:

    <xcad:DockingManager Name="_dockingManager" Grid.Row="1" 
DataContext="{Binding DockingManagerViewModel}"
                     DocumentsSource="{Binding Documents}"
                     AnchorablesSource="{Binding Anchorables}" > 

因此,当我在视图模型中将新的Anchorable添加到相应的“ Anchorables”集合时,就会显示相应的视图。但是,视图始终显示在应用程序的右侧。如何通过视图模型控制视图是否停靠在应用程序的左侧?

2 个答案:

答案 0 :(得分:0)

我认为您无法在视图模型中控制它。

有2种控制方式。

  1. 每当您将布局从以前保存的(默认)布局中恢复时,  第一次启动应用程序或

  2. 您可以将XAML设置为根据需要使用初始布局(首选解决方案)

对于第二个选项: 您可以在DockingManager类中使用XAML绑定来实现您的要求:

请参阅TestApp示例以获取以下代码段的完整实现(只需将LeftSide更改为BottomSide即可查看效果):

<avalonDock:DockingManager Grid.Row="1">
...
    <avalonDock:LayoutRoot.LeftSide>
        <avalonDock:LayoutAnchorSide>
            <avalonDock:LayoutAnchorGroup>
                <avalonDock:LayoutAnchorable Title="AutoHide1 Content" ContentId="AutoHide1Content" IconSource="/AvalonDock.TestApp;component/Images/address-book--pencil.png" >
                    <TextBox Text="{Binding TestTimer, Mode=OneWay, StringFormat='AutoHide Attached to Timer ->\{0\}'}"/>
                </avalonDock:LayoutAnchorable>
                <avalonDock:LayoutAnchorable Title="AutoHide2 Content" ContentId="AutoHide2Content">
                    <StackPanel Orientation="Vertical">
                        <TextBox/>
                        <TextBox/>
                    </StackPanel>
                </avalonDock:LayoutAnchorable>
            </avalonDock:LayoutAnchorGroup>
        </avalonDock:LayoutAnchorSide>
    </avalonDock:LayoutRoot.LeftSide>
</avalonDock:LayoutRoot>
</avalonDock:DockingManager>

答案 1 :(得分:0)

您可以在Anchorable视图模型中添加一个属性(称为InitialPosition或类似名称),并实现ILayoutUpdateStrategy以将可定位对象定位在左侧,右侧或底部。 / p>

向您的XAML中添加类似的内容

<xcad:DockingManager …>
   …
   <xcad:DockingManager.LayoutUpdateStrategy>
        <local:LayoutUpdate />
   </xcad:DockingManager.LayoutUpdateStrategy>

</xcad:DockingManager>

和您的LayoutUpdate类:

class LayoutUpdate: ILayoutUpdateStrategy
{
    static Dictionary<PaneLocation, string> _paneNames = new Dictionary<PaneLocation, string>
    {
        { PaneLocation.Left, "LeftPane" },
        { PaneLocation.Right, "RightPane" },
        { PaneLocation.Bottom, "BottomPane" },
    };

    public bool BeforeInsertAnchorable(LayoutRoot layout, LayoutAnchorable anchorableToShow, ILayoutContainer destinationContainer)
    {
        if (anchorableToShow.Content is IAnchorable anch)
        {
            var initLocation = anch.InitialLocation;
            string paneName = _paneNames[initLocation];
            var anchPane = layout.Descendents()
                           .OfType<LayoutAnchorablePane>()
                           .FirstOrDefault(d => d.Name == paneName);

            if (anchPane == null)
            {
                 anchPane = CreateAnchorablePane(layout, Orientation.Horizontal, initLocation);
            }
            anchPane.Children.Add(anchorableToShow);
            return true;
        }

        return false;
    }

    static LayoutAnchorablePane CreateAnchorablePane(LayoutRoot layout, Orientation orientation,
                PaneLocation initLocation)
    {
        var parent = layout.Descendents().OfType<LayoutPanel>().First(d => d.Orientation == orientation);
        string paneName = _paneNames[initLocation];
        var toolsPane = new LayoutAnchorablePane { Name = paneName };
        if (initLocation == PaneLocation.Left)
            parent.InsertChildAt(0, toolsPane);
        else
            parent.Children.Add(toolsPane);
        return toolsPane;
    }

    public void AfterInsertAnchorable(LayoutRoot layout, LayoutAnchorable anchorable)
    {
        // here set the initial dimensions (DockWidth or DockHeight, depending on location) of your anchorable
    }

此代码是从工作应用程序中提取并更改的,它具有不同的类型和名称。可能应该可以,但是某处可能有错字或其他错误。