在浏览StackOverflow和其他网站后,我发现人们对MenuItems
和ContextMenus
的绑定属性和命令存在很多问题,因为ContextMenu
不属于WPF视觉树。无论如何,我尝试了一些不同的解决方案,但没有运气。
我有MenuItem
,是ContextMenu
的一部分。 ContextMenu
是窗口的一部分,该窗口在其代码后面绑定到ViewModel,如下所示:
public partial class Window1 : Window
{
public MainWindowViewModel ViewModel { get { return DataContext as MainWindowViewModel; } }
public Window1()
{
InitializeComponent();
//There is a property in the App.xaml.cs file that refers to MainWindowViewModel
DataContext = App.MainWindowViewModel = new MainWindowViewModel();
}
}
我尝试在MainWindowViewModel
中绑定的属性:
private bool _askBeforeDownloading_Checked = true;
public bool AskBeforeDownloading_Checked
{
get { return _askBeforeDownloading_Checked; }
set
{
_askBeforeDownloading_Checked = value;
NotifyPropertyChange(() => AskBeforeDownloading_Checked);
}
}
我目前在XAML中的尝试:
<Button Name="Button_1" >
<Button.ContextMenu>
<ContextMenu x:Name="MainContextMenu" DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}" >
<MenuItem >
<MenuItem IsCheckable="True" IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget.AskBeforeDownloading_Checked}" />
</MenuItem>
</ContextMenu>
</Button.ContextMenu>
</Button>
我根据this question上接受的答案以及this guide提出了我当前的XAML。我错过了什么?我没有收到任何输出错误,但未检查MenuItem
。我有没有用PlacementTarget
做什么?
更新:我认为重要的是要注意我的ContextMenu
是Button
的子控件。我已将它添加到我的XAML中。
更新2 :在我的应用程序上使用Snoop后,我发现我的Button
会自动从MainWindowViewModel
继承。但是,我忽略了可能会影响我的代码的父MenuItem
。我已经更新了我的XAML并为第一次错过而道歉。
答案 0 :(得分:2)
DataContext
继承自<ContextMenu>
,因此您无需在绑定中编写任何特殊内容。
<Button Name="Button_1" >
<Button.ContextMenu>
<ContextMenu x:Name="MainContextMenu" DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}" >
<MenuItem IsCheckable="True" IsChecked="{Binding AskBeforeDownloading_Checked}" />
</ContextMenu>
</Button.ContextMenu>
</Button>
为了更详细地解释,DataContext
中的<ContextMenu>
绑定说:
<ContextMenu>
<Button>
对象所以你说要将ContextMenu.DataContext
属性绑定到Button.DataContext
属性。
该属性应该是您的MainWindowViewModel
,因此您可以使用普通绑定绑定到DataContext上的.AskBeforeDownloading_Checked
属性。
或者,您可以从.DataContext
删除<ContextMenu>
绑定,并保持<MenuItem>
绑定与您拥有的绑定类似,但您需要引用Button.DataContext.AskBeforeDownloading_Checked
},而不是你现在拥有的Button.AskBeforeDownloading_Checked
。
<Button Name="Button_1" >
<Button.ContextMenu>
<ContextMenu x:Name="MainContextMenu>
<MenuItem IsCheckable="True" IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget.DataContext.AskBeforeDownloading_Checked}" />
</ContextMenu>
</Button.ContextMenu>
</Button>
在这两种方法中,我更喜欢第一种方法,因为如果你将更多的项目/属性绑定到Button.DataContext
属性,它允许更少的代码。
答案 1 :(得分:1)
您需要添加PlacementTarget.DataContext。请参阅下面的代码。
<Button Name="Button_1" >
<Button.ContextMenu>
<ContextMenu x:Name="MainContextMenu">
<MenuItem IsCheckable="True" IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget.DataContext.AskBeforeDownloading_Checked}" />
</ContextMenu>
</Button.ContextMenu>
</Button>