gpt4 book ai didi

wpf - 如何将 MenuItem.Header 绑定(bind)到 Window/UserControl 依赖属性?

转载 作者:行者123 更新时间:2023-12-04 19:22:26 28 4
gpt4 key购买 nike

我想知道如何将 MenuItem.Header 绑定(bind)到父 Window/UserControl 依赖属性?这是一个简单的例子:

Window1.xaml :

<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300" x:Name="self">
<Grid>
<Grid.ContextMenu>
<ContextMenu>
<MenuItem Header="{Binding Path=MenuText, ElementName=self}" />
</ContextMenu>
</Grid.ContextMenu>
<TextBlock Text="{Binding Path=MenuText, ElementName=self}"/>
</Grid>
</Window>

Window1.xaml.cs :
public partial class Window1 : Window {
public static readonly DependencyProperty MenuTextProperty = DependencyProperty.Register(
"MenuText", typeof (string), typeof (Window1), new PropertyMetadata("Item 1"));

public Window1()
{
InitializeComponent();
}

public string MenuText {
get { return (string)this.GetValue(MenuTextProperty); }
set { this.SetValue(MenuTextProperty, value); }
}
}

在我的情况下,文本 block 显示“项目 1”,上下文菜单显示空项目。我做错了什么?在我看来,我面临着对 WPF 数据绑定(bind)原则的严重误解。

最佳答案

您应该在 Visual Studio 的输出窗口中看到:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=self'. BindingExpression:Path=MenuText; DataItem=null; target element is 'MenuItem' (Name=''); target property is 'Header' (type 'Object')



那是因为 ContextMenu 与 VisualTree 断开连接,您需要以不同的方式执行此 Binding。

一种方法是通过 ContextMenu.PlacementTarget (应该是 Grid),您可以使用它的 DataContext 来建立绑定(bind),例如:
<MenuItem Header="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.DataContext.MenuText}"/>

或在 ContextMenu 本身中设置 DataContext:
<ContextMenu DataContext="{Binding RelativeSource={RelativeSource Self}, Path=PlacementTarget.DataContext}">
<MenuItem Header="{Binding Path=MenuText}"/>
</ContextMenu>

如果这不是一个选项(因为 Grid 的 DataContext 不能是 Window/UserControl),您可以尝试通过 Tag 传递对 Window/UserControl 的引用。例如你的网格。
<Grid ...
Tag="{x:Reference self}">
<Grid.ContextMenu>
<!-- The DataContext is now bound to PlacementTarget.Tag -->
<ContextMenu DataContext="{Binding RelativeSource={RelativeSource Self}, Path=PlacementTarget.Tag}">
<MenuItem Header="{Binding Path=MenuText}"/>
</ContextMenu>
...

附带说明:由于这种行为,我倾向于在 App.xaml 中定义帮助器样式。使所有 ContextMenus 从其父级“伪继承” DataContext:
    <!-- Context Menu Helper -->
<Style TargetType="{x:Type ContextMenu}">
<Setter Property="DataContext" Value="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}"/>
</Style>

关于wpf - 如何将 MenuItem.Header 绑定(bind)到 Window/UserControl 依赖属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5781688/

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