views:

38

answers:

1

I have this Tree View that looks like this:

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

And here is my click event

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

I am trying to write the EditProject_Click event for the ContextMenu MenuItem click event. When I click it, I want to be able to find the item Bound to the node that the context menu resides. How do I do that?


The answer

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

        //Do stuff with the project here
    }

Also, if you want to get your ContextMenu to update it's DataContext from the element the ContextMenu is suppose to be attached to, here is the syntax for that:

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

In the click event handler, would "(sender as FrameworkElement).DataContext" be what you're looking for?

EDIT:

Sample code below.

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

}
karmicpuppet
Actually no. I can get the DataContext from the MenuItem the first time. But if I change the items in the Tree and the tree updates, for whatever reason, the context menu menu item's refuse to update their DataContext, so everything within the ContextMenu is still bound to the wrong object.I can't figure out how to get my ContextMenu's to keep their DataContext to be the same as their parent element.
Ristogod
You probably have a different problem here. (Maybe related to property changed notifications or something). Anyway, see my Edit. I wrote a little test app showing that my answer works, even if the TreeView's ItemsSource got changed.
karmicpuppet
I determined my issue with the context menu losing it's binding to its parent element. See above to see my answer on how to fix.
Ristogod