2010-08-24 10 views
4

Je cette Tree View qui ressemble à ceci:Trouver Bound Point de TreeViewItem de ContextMenu

 <TreeView 
       Grid.Column="0" 
       Grid.Row="2" 
       MinHeight="100" 
       MinWidth="100" 
       BorderBrush="White" 
       DataContext="{Binding Projects, Source={x:Static SizingApp:Manager.Instance}}"> 
       <TreeView.Resources> 
        <Style TargetType="TreeViewItem"> 
         <Setter Property="IsExpanded" Value="True" /> 
        </Style> 
        <DataTemplate x:Key="LoadTemplate"> 
         <TextBlock Text="{Binding Name}"> 
          <TextBlock.ContextMenu> 
           <ContextMenu> 
            <MenuItem InputGestureText="{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=load_ContextMenu_Edit_InputGestureText}"> 
             <MenuItem.Header> 
              <TextBlock Text="{Binding Path=Name, 
                      StringFormat={Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=load_ContextMenu_Edit_Header}}" /> 
             </MenuItem.Header> 
            </MenuItem> 
            <MenuItem> 
             <MenuItem.Header> 
              <TextBlock Text="{Binding Path=Name, 
                      StringFormat={Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=load_ContextMenu_Save_Header}}" /> 
             </MenuItem.Header> 
            </MenuItem> 
            <MenuItem> 
             <MenuItem.Header> 
              <TextBlock Text="{Binding Path=Name, 
                      StringFormat={Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=load_ContextMenu_Export_Header}}" /> 
             </MenuItem.Header> 
            </MenuItem> 
            <MenuItem Header="{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=load_ContextMenu_Copy_Header}" 
                    InputGestureText="{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=load_ContextMenu_Copy_InputGestureText}"/> 
            <MenuItem InputGestureText="{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=load_ContextMenu_Remove_InputGestureText}"> 
             <MenuItem.Header> 
              <TextBlock Text="{Binding Path=Name, 
                      StringFormat={Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=load_ContextMenu_Remove_Header}}" /> 
             </MenuItem.Header> 
            </MenuItem> 
           </ContextMenu> 
          </TextBlock.ContextMenu> 
         </TextBlock> 
        </DataTemplate> 
        <HierarchicalDataTemplate x:Key="StepTemplate" 
          ItemsSource="{Binding Loads}" 
          ItemTemplate="{StaticResource LoadTemplate}"> 
         <TextBlock Text="{Binding Name}"> 
          <TextBlock.ContextMenu> 
           <ContextMenu> 
            <MenuItem InputGestureText="{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=step_ContextMenu_Edit_InputGestureText}"> 
             <MenuItem.Header> 
              <TextBlock Text="{Binding Path=Name, 
                   StringFormat={Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=step_ContextMenu_Edit_Header}}" /> 
             </MenuItem.Header> 
            </MenuItem> 
            <MenuItem Header="{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=step_ContextMenu_Copy_Header}" 
                 InputGestureText="{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=step_ContextMenu_Copy_InputGestureText}" /> 
            <MenuItem Header="{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=step_ContextMenu_Paste_Header}" 
                 InputGestureText="{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=step_ContextMenu_Paste_InputGestureText}" /> 
            <MenuItem Header="{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=step_ContextMenu_Import_Load_Header}" /> 
            <MenuItem> 
             <MenuItem.Header> 
              <TextBlock Text="{Binding Path=Name, 
                   StringFormat={Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=step_ContextMenu_Export_Header}}" /> 
             </MenuItem.Header> 
            </MenuItem> 
            <MenuItem InputGestureText="{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=step_ContextMenu_Remove_InputGestureText}"> 
             <MenuItem.Header> 
              <TextBlock Text="{Binding Path=Name, 
                   StringFormat={Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=step_ContextMenu_Remove_Header}}" /> 
             </MenuItem.Header> 
            </MenuItem> 
            <MenuItem Header="{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=step_ContextMenu_Add_Load_Header}" 
                 ItemsSource="{StaticResource mnuLoadSubmenuCommon}"/> 
           </ContextMenu> 
          </TextBlock.ContextMenu> 
         </TextBlock> 
        </HierarchicalDataTemplate> 
        <HierarchicalDataTemplate x:Key="ProjectTemplate" 
          ItemsSource="{Binding Steps}" 
          ItemTemplate="{StaticResource StepTemplate}"> 
         <TextBlock Text="{Binding Name}"> 
          <TextBlock.ContextMenu> 
           <ContextMenu> 
            <MenuItem InputGestureText="{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=project_ContextMenu_Edit_InputGestureText}" 
               Click="EditProject_Click"> 
             <MenuItem.Header> 
              <TextBlock Text="{Binding Path=Name, 
                StringFormat={Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=project_ContextMenu_Edit_Header}}" /> 
             </MenuItem.Header> 
            </MenuItem> 
            <MenuItem> 
             <MenuItem.Header> 
              <TextBlock Text="{Binding Path=Name, 
                StringFormat={Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=project_ContextMenu_Save_Header}}" /> 
             </MenuItem.Header> 
            </MenuItem> 
            <MenuItem Header="{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=project_ContextMenu_Copy_Header}" 
              InputGestureText="{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=project_ContextMenu_Copy_InputGestureText}" /> 
            <MenuItem Header="{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=project_ContextMenu_Paste_Header}" 
              InputGestureText="{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=project_ContextMenu_Paste_InputGestureText}" /> 
            <MenuItem InputGestureText="{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=project_ContextMenu_Remove_InputGestureText}"> 
             <MenuItem.Header> 
              <TextBlock Text="{Binding Path=Name, 
                StringFormat={Resx ResxName=PSSPECApplication.Controls.ProjectControlResources,Key=project_ContextMenu_Remove_Header}}" /> 
             </MenuItem.Header> 
            </MenuItem> 
            <MenuItem Header="{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources, Key=projectTree_Project_AddStep_Header}" /> 
            <MenuItem Header="{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources, Key=projectTree_Project_ImportStep_Header}" /> 
           </ContextMenu> 
          </TextBlock.ContextMenu> 
         </TextBlock> 
        </HierarchicalDataTemplate> 
       </TreeView.Resources> 
       <TreeViewItem 
         Header="{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources, Key=projectTree_Header}" 
         ItemsSource="{Binding}" 
         IsExpanded="True" 
         ItemTemplate="{StaticResource ProjectTemplate}"> 
        <TreeViewItem.ContextMenu> 
         <ContextMenu> 
          <MenuItem Header="{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources, Key=projectTree_Paste_Header}" 
            InputGestureText="{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources, Key=projectTree_Paste_InputGestureText}" /> 
         </ContextMenu> 
        </TreeViewItem.ContextMenu> 
       </TreeViewItem> 
      </TreeView> 

Et voici mon événement click

private void EditProject_Click(object sender, RoutedEventArgs e) 
    { 
     //how do I find the bound item of the node this context menu resides on? 
    } 

Je suis en train d'écrire l'événement EditProject_Click pour la ContextMenu MenuItem cliquez sur l'événement. Lorsque je clique dessus, je veux être capable de trouver l'élément lié au nœud que le menu contextuel réside. Comment je fais ça?


La réponse

private void EditProject_Click(object sender, RoutedEventArgs e) 
    { 
     Project project = (Project)((MenuItem)sender).DataContext; 

     //Do stuff with the project here 
    } 

, si vous voulez également obtenir votre ContextMenu mettre à jour c'est DataContext de l'élément ContextMenu est supposé être attaché à, voici la syntaxe que:

<ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}"> 
+1

J'ai ajouté la réponse. – Ristogod

+0

cette réponse a besoin de plus d'upvote, j'ai cherché cette solution pendant des semaines! – HypeZ

Répondre

6

Dans le gestionnaire d'événements click, "(expéditeur en tant que FrameworkElement) .DataContext" correspondrait-il à ce que vous recherchez?

EDIT:

Exemple de code ci-dessous.

XAML:

<Window x:Class="WpfApplication3.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:v="clr-namespace:WpfApplication3" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 
     <DataTemplate x:Key="template"> 
      <TextBlock Text="{Binding}"> 
       <TextBlock.ContextMenu> 
        <ContextMenu> 
         <MenuItem Header="Test" Click="MenuItem_Click"/> 
        </ContextMenu> 
       </TextBlock.ContextMenu> 
      </TextBlock> 
     </DataTemplate> 
    </Window.Resources> 
    <DockPanel> 
     <Button DockPanel.Dock="Top" Click="Button_Click">Change Context</Button> 

     <TreeView x:Name="tv" ItemTemplate="{StaticResource template}"/> 

    </DockPanel> 

</Window> 

code-behind:


public partial class MainWindow : Window 
{ 
    bool flag = false; 
    public MainWindow() 
    { 
     InitializeComponent(); 
     List list = new List() { "A", "B", "C", "D" }; 
     this.tv.ItemsSource = list; 
    } 
    private void MenuItem_Click(object sender, RoutedEventArgs e) 
    { 
     MessageBox.Show((sender as MenuItem).DataContext.ToString()); 
    } 
    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     if (flag) 
     { 
      List list = new List() { "A", "B", "C", "D" }; 
      this.tv.ItemsSource = list; 
     } 
     else 
     { 
      List list = new List() { 1, 2, 3, 4 }; 
      this.tv.ItemsSource = list; 
     } 
     flag = !flag; 
    } 

}
+0

En fait non. Je peux obtenir le DataContext à partir du MenuItem la première fois. Mais si je change les éléments dans l'arborescence et l'arborescence, pour une raison quelconque, l'élément de menu du menu contextuel refuse de mettre à jour leur DataContext, donc tout dans le ContextMenu est toujours lié au mauvais objet. Je n'arrive pas à comprendre comment obtenir que mes ContextMenu conservent leur DataContext comme étant leur élément parent. – Ristogod

+0

Vous avez probablement un problème différent ici. (Peut-être lié à la propriété a changé les notifications ou quelque chose). Quoi qu'il en soit, voir mon Edit. J'ai écrit une petite application de test montrant que ma réponse fonctionne, même si la source Items de TreeView a été modifiée. – ASanch

+0

J'ai déterminé mon problème avec le menu contextuel en perdant sa liaison à son élément parent. Voir ci-dessus pour voir ma réponse sur la façon de résoudre. – Ristogod