2014-01-03 8 views
3

У меня есть простая задача привязать контекстное меню к элементам TreeView. Если я определяю контекстное меню, статически не проблема. Но если я хочу привязать контекстное меню к моему «корневому» контексту данных, все начинает ломаться. До сих пор мне не удалось найти правильный способ привязки моего контекстного меню к исходному DataContext, который использует TreeView. Какая обязательная магия нужна для этого? Это Binding не работает:ContextMenu Связывание с TreeView

<MenuItem Name="Name" Header="{Binding Path=DataContext.ContextMenuName, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeView}}}" /> 

Ниже приводится полный пример:

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:sys="clr-namespace:System;assembly=mscorlib" 
     xmlns:ui="clr-namespace:WpfApplication1" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <TreeView ItemsSource="{Binding Path=Persons, Mode=OneTime}" Name="cTree"> 
      <TreeView.ItemTemplate> 
       <HierarchicalDataTemplate> 
        <TextBox Text="{Binding Mode=OneWay}"> 
         <TextBox.ContextMenu> 
          <ContextMenu> 
           <MenuItem Name="Name" Header="{Binding Path=DataContext.ContextMenuName, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeView}}}" /> 
          </ContextMenu> 
         </TextBox.ContextMenu> 
        </TextBox> 
       </HierarchicalDataTemplate> 
      </TreeView.ItemTemplate> 
     </TreeView> 
    </Grid> 
</Window> 



public partial class MainWindow : Window 
{ 
    public string[] Persons 
    { 
     get { return new string[] { "Alois", "Kraus", "Joe", "xxxx" }; } 
    } 

    public string ContextMenuName 
    { 
     get; 
     set; 
    } 

    public MainWindow() 
    { 
     ContextMenuName = "This is the data bound menu name"; 
     InitializeComponent(); 
     this.DataContext = this; 
    } 
} 

В основном я хочу, чтобы связать свойство ContextMenuName (на самом деле команда в моей ViewModel) основной формы. Поскольку TreeView переписывает свои дочерние элементы Лицам (строки, чтобы сохранить их просто), я не могу извлечь из него корневой DataContext. До сих пор мне не удалось найти какого-либо предка (TreeView или MainWindow), который должен решить проблему? Что я здесь делаю неправильно?

ответ

6

ContextMenuне лежит в том же визуальном дереве, как и из-под контроля, на которой она применяется. Таким образом, FindAncestor не сможет добраться до TreeView, поскольку он не является предком ContextMenu.

Также ElementName не будет работать здесь, так как ему также необходимо, чтобы два элемента управления находились в одном и том же Визуальном дереве.

Вы можете использовать x:Reference, который позволяет связать даже если они не лежат в одном визуальном дереве:

<MenuItem Name="Name" 
      Header="{Binding Path=DataContext.ContextMenuName, 
          Source={x:Reference cTree}}" /> 
+2

Это сделало трюк! Я прочитал много вопросов о привязке данных, но Source и Reference никогда не отображались во время моего поиска. Большое спасибо, что мне стоило довольно много времени. –

+0

Ваш приветствующий Alois .. :) –

+1

Возможно, 4-6 часов поиска, прежде чем вы решили мою проблему. +1. – Hosch250

0

Вы пытались связать через ElementName=cTree вместо RelativeSource={...}?

+0

Да что же тоже не работает. –

Смежные вопросы