wpf - 在 Window.Resources 中的 DataTemplate 中绑定(bind)到拥有窗口的 View 模型中的属性

标签 wpf datatemplate

我的 Window 的 Resources 部分中有一个 DataTemplate,它创建一个带有 ContextMenu 的 TextBlock。我希望能够设置 ContextMenu 中的 MenuItem 在我的 Window View 模型中是否可见。我尝试通过设置 ElementName 来访问窗口的 DataContext ,并尝试设置 RelativeSource ,但两种方法都会导致绑定(bind)错误。我不确定我还能尝试什么。

我创建了一个小例子来展示我正在尝试做的事情:

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));
        }
    }
}

我得到的错误是

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=Root'. BindingExpression:Path=DataContext.MenuItemVisible; DataItem=null; target element is 'MenuItem' (Name=''); target property is 'Visibility' (type 'Visibility')



当我在绑定(bind)中设置 RelativeSource 而不是 ElementName 时:
RelativeSource={RelativeSource Mode=FindAncestor, 
                AncestorType={x:Type ScrollViewer}}

我收到以下错误:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ScrollViewer', AncestorLevel='1''. BindingExpression:Path=DataContext.MenuItemVisible; DataItem=null; target element is 'MenuItem' (Name=''); target property is 'Visibility' (type 'Visibility')

最佳答案

我找到了答案here :
所以我需要做的就是访问窗口的 DataContext :

Source={x:Reference Name=Root}
找到了为什么 ElementName 在这种情况下不起作用的解释 here .具体来说:

Probably the simplest example of where we don't have inheritance context links is across > random property elements:

<Button>
  <Button.ContextMenu>
    <ContextMenu/>
  </Button.ContextMenu>
</Button>

ContextMenu is neither a visual nor logical child of Button, nor is it one of the inheritance context cases listed above (ContextMenu is not a Freezable).

关于wpf - 在 Window.Resources 中的 DataTemplate 中绑定(bind)到拥有窗口的 View 模型中的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11017014/

相关文章:

c# - Mvvm在窗口中拖动网格

wpf - 在 WPF 中旋转 3D 立方体

wpf - 我应该使用 DataTemplates 还是 UserControl 来显示扩展类的不同控件?

c# - 如何创建具有可变数量 StackPanel 的 StackPanel 的 DataTemplate

c# - 围绕对象wpf的中心旋转相机

c# - 没有 setter 的属性的数据绑定(bind)

c# - WPF MySQL 连接错误处理

wpf - 从 DataTemplate 内的资源绑定(bind)

wpf - WPF 中的条件数据模板

c# - ItemsControl 上的设计时 ItemsSource