我的窗口的参考资料部分中有一个DataTemplate,它使用ContextMenu创建一个TextBlock。我希望能够设置ContextMenu中的MenuItem是否可以从窗口的视图模型中看到。我尝试通过设置ElementName
访问窗口的DataContext,也尝试设置RelativeSource
,但这两种方法都导致绑定错误。我不确定我还能尝试什么。
我创建了一个小示例,展示了我正在尝试做的事情:
XAML:
<Window x:Class="DataTemplateTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ResourceDictionary>
<DataTemplate x:Key="TestDataTemplate">
<TextBlock Text="{Binding}">
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem Header="Test" Visibility="{Binding Path=DataContext.MenuItemVisible, ElementName=Root}"/>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</DataTemplate>
</ResourceDictionary>
</Window.Resources>
<ScrollViewer x:Name="Root">
<ItemsControl ItemsSource="{Binding Path=Items}" ItemTemplate="{StaticResource TestDataTemplate}" />
</ScrollViewer>
代码隐藏:
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
namespace DataTemplateTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
protected readonly MainWindowViewModel vm;
public MainWindow()
{
InitializeComponent();
vm = new MainWindowViewModel();
DataContext = vm;
}
}
public class MainWindowViewModel : INotifyPropertyChanged
{
private Visibility menuItemVisible = Visibility.Hidden;
public Visibility MenuItemVisible { get { return menuItemVisible; } set { menuItemVisible = value; NotifyPropertyChanged("MenuItemVisible"); } }
public List<string> Items { get; set; }
public MainWindowViewModel()
{
Items = new List<string>() { "Alpha", "Beta", "Gamma" };
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
我得到的错误是
系统。窗户。数据错误: 4:无法找到与引用'ElementName=Root'绑定的源。绑定表达式:路径=数据上下文。MenuItemVible; DataItem=null;目标元素是'MenuItem'(Name=");目标属性是'可见性'(类型'可见性')
在绑定中设置RelativeSource而不是ElementName时:
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type ScrollViewer}}
我得到以下错误:
系统。窗户。数据错误: 4:无法找到与引用'RelativeSource FindAncestor, AncestorType='System绑定的源。窗户。控件。ScrollViewer', AncestorLevel='1"。绑定表达式:路径=数据上下文。MenuItemVible; DataItem=null;目标元素是'MenuItem'(Name=");目标属性是'可见性'(类型'可见性')
我在这里找到了答案:
因此,我所要做的访问窗口的DataContext设置:
Source={x:Reference Name=Root}
此处可以找到为什么ElementName在这种情况下不起作用的解释。具体而言:
可能我们没有继承上下文链接的最简单的例子是跨
<Button>
<Button.ContextMenu>
<ContextMenu/>
</Button.ContextMenu>
</Button>
ContextMenu既不是Button的视觉子级,也不是Button的逻辑子级,也不是上面列出的继承上下文案例之一(ContextMenu不是可自由释放的)。