本文介绍了在Window.Resources中的数据模板中绑定拥有窗口的视图模型中的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在窗口的资源部分中有一个DataTemplate,它可以使用ContextMenu创建一个TextBlock。我希望能够设置从我的窗口的视图模型中是否可以看到ContextMenu中的MenuItem。我尝试通过设置 ElementName 访问窗口的DataContext,还尝试设置 RelativeSource ,但是两种方法都导致绑定错误。我不确定我还能尝试什么。

I have a DataTemplate within my Window's Resources section that creates a TextBlock with a ContextMenu. I want to be able to set whether a MenuItem within the ContextMenu is visible from within my Window's view model. I have tried accessing the DataContext of the Window by setting ElementName, and also tried setting RelativeSource, but both approaches resulted in binding errors. I'm not sure what else I can try.

我创建了一个小示例,显示了我正在尝试做的事情:

I have created a small example that shows what I'm trying to do:

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

我得到的错误是

在绑定中设置RelativeSource而不是ElementName时:

When I set RelativeSource instead of ElementName in the binding:

RelativeSource={RelativeSource Mode=FindAncestor, 
                AncestorType={x:Type ScrollViewer}}

我收到以下错误:


推荐答案

I在:

因此,我需要做的所有工作才能访问设置了窗口的DataContext:

So all I had to do to access the window's DataContext was set:

Source={x:Reference Name=Root}

找到了为什么在这种情况下ElementName不起作用的说明。具体来说:

An explanation of why ElementName does not work in this case is found here. Specifically:

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

ContextMenu既不是Button的视觉子元素也不是逻辑子元素,也不是上面列出的继承上下文案例之一(ContextMenu是不是Freezable)。

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).

这篇关于在Window.Resources中的数据模板中绑定拥有窗口的视图模型中的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 07:09