gpt4 book ai didi

c# - 绑定(bind) AvalonDock LayoutAnchorable IsVisible 属性

转载 作者:行者123 更新时间:2023-12-04 13:12:30 34 4
gpt4 key购买 nike

我正在尝试将 AvalonDock LayoutAnchorables 绑定(bind)到 WPF 中它们各自的菜单项。如果在菜单中选中, anchor 应该是可见的。如果未在菜单中选中,应隐藏 anchor 。

IsCheckedIsVisible 都是 bool 值,所以我认为不需要转换器。我可以将 LayoutAnchorable IsVisible 属性设置为 TrueFalse,并且行为符合设计 View 中的预期。

但是,如果尝试按如下方式实现绑定(bind),则会出现错误

'Binding' cannot be set on the 'IsVisible' property of type'LayoutAnchorable'. A 'Binding' can only be set on aDependencyProperty of a DependencyObject.

问题出在这里:

<dock:LayoutAnchorable ContentId="content1" IsVisible="{Binding IsChecked, ElementName=mnuPane1}" x:Name="anchorable1" IsSelected="True">

我该怎么做?

<Window x:Class="TestAvalonBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:dock="http://schemas.xceed.com/wpf/xaml/avalondock"
mc:Ignorable="d"
Title="MainWindow"
Height="450"
Width="800">
<Grid>

<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>

<!-- Menu -->
<Menu Height="18" HorizontalAlignment="Stretch" Name="menu1" VerticalAlignment="Top" Grid.Row="0">
<MenuItem Header="File">
<MenuItem Header="_Foo1" Name="mnuPane1" IsCheckable="True">
</MenuItem>
<MenuItem Header="Foo2" Name="mnuPane2" IsCheckable="True">
</MenuItem>
</MenuItem>
</Menu>

<!-- AvalonDock -->
<dock:DockingManager x:Name="Dockman" DockPanel.Dock="Left" Grid.Row="1" >

<dock:LayoutRoot x:Name="_layoutRoot">
<dock:LayoutPanel Orientation="Horizontal">
<dock:LayoutAnchorablePaneGroup Orientation="Vertical">
<dock:LayoutAnchorablePane FloatingWidth="150" FloatingHeight="150" FloatingLeft="100" FloatingTop="300">
<dock:LayoutAnchorable ContentId="content1" IsVisible="{Binding IsChecked, ElementName=mnuPane1}" x:Name="anchorable1" IsSelected="True">
<GroupBox Header="Foo1"/>
</dock:LayoutAnchorable>
</dock:LayoutAnchorablePane>
<dock:LayoutAnchorablePane FloatingWidth="150" FloatingHeight="150" FloatingLeft="100" FloatingTop="300">
<dock:LayoutAnchorable ContentId="content2" x:Name="anchorable2" IsSelected="True">
<GroupBox Header="Foo2"/>
</dock:LayoutAnchorable>
</dock:LayoutAnchorablePane>
</dock:LayoutAnchorablePaneGroup>
</dock:LayoutPanel>
</dock:LayoutRoot>
</dock:DockingManager>

</Grid>
</Window>

更新:

我对 BionicCode 答案的实现。我剩下的问题是,如果我关闭一个 Pane ,菜单项将保持选中状态。

XAML

<Grid>

<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>

<!-- Menu -->
<Menu Height="18" HorizontalAlignment="Stretch" Name="menu1" VerticalAlignment="Top" Grid.Row="0">
<MenuItem Header="File">
<MenuItem Header="_Foo1" Name="mnuPane1" IsCheckable="True" IsChecked="{Binding RelativeSource={RelativeSource AncestorType=local:MainWindow}, Path=IsAnchorable1Visible}"/>
<MenuItem Header="Foo2" Name="mnuPane2" IsCheckable="True" IsChecked="{Binding RelativeSource={RelativeSource AncestorType=local:MainWindow}, Path=IsAnchorable2Visible}"/>
</MenuItem>
</Menu>

<!-- AvalonDock -->
<dock:DockingManager x:Name="Dockman" DockPanel.Dock="Left" Grid.Row="1" >
<dock:LayoutRoot x:Name="_layoutRoot">
<dock:LayoutPanel Orientation="Horizontal">
<dock:LayoutAnchorablePaneGroup Orientation="Vertical">
<dock:LayoutAnchorablePane FloatingWidth="150" FloatingHeight="150" FloatingLeft="100" FloatingTop="300">
<dock:LayoutAnchorable ContentId="content1" x:Name="anchorable1" IsSelected="True" >
<GroupBox Header="Foo1"/>
</dock:LayoutAnchorable>
</dock:LayoutAnchorablePane>
<dock:LayoutAnchorablePane FloatingWidth="150" FloatingHeight="150" FloatingLeft="100" FloatingTop="300">
<dock:LayoutAnchorable ContentId="content2" x:Name="anchorable2" IsSelected="True" >
<GroupBox Header="Foo2"/>
</dock:LayoutAnchorable>
</dock:LayoutAnchorablePane>
</dock:LayoutAnchorablePaneGroup>
</dock:LayoutPanel>
</dock:LayoutRoot>
</dock:DockingManager>

</Grid>

代码隐藏

partial class MainWindow : Window
{
public static readonly DependencyProperty IsAnchorable1VisibleProperty = DependencyProperty.Register(
"IsAnchorable1Visible",
typeof(bool),
typeof(MainWindow),
new PropertyMetadata(default(bool), MainWindow.OnIsAnchorable1VisibleChanged));

public static readonly DependencyProperty IsAnchorable2VisibleProperty = DependencyProperty.Register(
"IsAnchorable2Visible",
typeof(bool),
typeof(MainWindow),
new PropertyMetadata(default(bool), MainWindow.OnIsAnchorable2VisibleChanged));

public bool IsAnchorable1Visible
{
get => (bool)GetValue(MainWindow.IsAnchorable1VisibleProperty);
set => SetValue(MainWindow.IsAnchorable1VisibleProperty, value);
}
public bool IsAnchorable2Visible
{
get => (bool)GetValue(MainWindow.IsAnchorable2VisibleProperty);
set => SetValue(MainWindow.IsAnchorable2VisibleProperty, value);
}

public MainWindow()
{
InitializeComponent();
this.IsAnchorable1Visible = true;
this.IsAnchorable2Visible = true;
}

private static void OnIsAnchorable1VisibleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as MainWindow).anchorable1.IsVisible = (bool)e.NewValue;
}
private static void OnIsAnchorable2VisibleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as MainWindow).anchorable2.IsVisible = (bool)e.NewValue;
}
}

最佳答案

AvalonDock XAML 布局元素既不是控件也不是 UIElement 的派生元素。它们充当普通模型(尽管它们扩展了 DependencyObject)。
LayoutAnchorable 的属性没有实现为 DependencyProperty,而是实现了 INotifyPropertyChanged(如前所述,布局元素充当控件的 View 模型) .因此,它们不支持数据出价(作为绑定(bind)目标)。

这些 XAML 布局元素中的每一个都有一个相应的控件,该控件实际上将作为 DataContext 与布局元素一起呈现。名称等于布局元素的名称,并附加了 Control 后缀。如果您想将这些控件或项目容器(例如 LayoutAnchorableItem)连接到您的 View 模型,则必须创建一个以该容器为目标的 Style。下一个缺陷是此容器的 DataContext 不是控件打算显示的数据模型,而是控件的内部模型。要访问您的 View 模型,您需要访问例如LayoutAnchorableControl.LayoutItem.Model(因为 LayoutAnchorableControl.DataContextLayoutAnchorable)。

作者显然迷失了方向,因为他们太急于使用 MVVM 实现控制本身(如他们的文档中所述),而忘记以 MVVM 客户端应用程序为目标。他们打破了常见的 WPF 模式。外面看起来不错,但里面不太好。

要解决您的问题,您必须在 View 中引入一个中间依赖属性。注册的属性更改回调将委托(delegate)可见性以切换可锚定的可见性。
同样重要的是要注意 AvalonDock 的作者没有使用 UIElement.Visibility 来处理可见性。他们引入了独立于框架属性的自定义可见性逻辑。

如前所述,始终存在纯模型驱动的方法,您可以通过提供 ILayoutUpdateStrategy 实现来布局初始 View 。然后定义样式以连接 View 和 View 模型。使用 XAML 布局元素对 View 进行硬编码会在更高级的场景中带来一定的不便。

LayoutAnchorable 公开了一个 Show()Close() 方法或 IsVisible 属性来处理可见性。您还可以在访问 LayoutAnchorableControl.LayoutItem 时绑定(bind)到命令(例如,从 ControlTemplate 中),这会返回一个 LayoutAnchorableItem。此 LayoutAnchorableItem 公开了一个 HideCommand

MainWindow.xaml

<Window>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>

<!-- Menu -->
<Menu Grid.Row="0">
<MenuItem Header="File">
<MenuItem Header="_Foo1"
IsCheckable="True"
IsChecked="{Binding RelativeSource={RelativeSource AncestorType=MainWindow}, Path=IsAnchorable1Visible}" />
</MenuItem>
</Menu>

<!-- AvalonDock -->
<dock:DockingManager Grid.Row="1" >
<dock:LayoutRoot>
<dock:LayoutPanel>
<dock:LayoutAnchorablePaneGroup>
<dock:LayoutAnchorablePane>
<dock:LayoutAnchorable x:Name="Anchorable1"
Hidden="Anchorable1_OnHidden">
<GroupBox Header="Foo1" />
</dock:LayoutAnchorable>
</dock:LayoutAnchorablePane>
</dock:LayoutAnchorablePaneGroup>
</dock:LayoutPanel>
</dock:LayoutRoot>
</dock:DockingManager>
</Grid>
</Window>

MainWindow.xaml.cs

partial class MainWindow : Window
{
public static readonly DependencyProperty IsAnchorable1VisibleProperty = DependencyProperty.Register(
"IsAnchorable1Visible",
typeof(bool),
typeof(MainWindow),
new PropertyMetadata(default(bool), MainWindow.OnIsAnchorable1VisibleChanged));

public bool IsAnchorable1Visible
{
get => (bool) GetValue(MainWindow.IsAnchorable1VisibleProperty);
set => SetValue(MainWindow.IsAnchorable1VisibleProperty, value);
}

public MainWindow()
{
InitializeComponent();
this.IsAnchorable1Visible = true;
}

private static void OnIsAnchorable1VisibleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as MainWindow).Anchorable1.IsVisible = (bool) e.NewValue;
}

private void Anchorable1_OnHidden(object sender, EventArgs e) => this.IsAnchorable1Visible = false;
}

关于c# - 绑定(bind) AvalonDock LayoutAnchorable IsVisible 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63645164/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com