Stretch41
Stretch41

Reputation:

How to get MenuItem clicked events from TreeView ContextMenu

I am inserting TreeViewItems into a TreeView control and setting the style for each at the time of insertion. I am assigning different styles (predefined in XAML), depending on the type of node (TreeViewItem) I want to insert. Some of the styles include a ContextMenu.

My problem is that I am unable to use Click="MyHandler" on the MenuItems; I get an error "root element requires a x:Class attribute to support event handlers in the XAML file." and apparently none of the elements within the Style block are root elements.

Any suggestions much appreciated.

XAML:

<Style x:Key="Terrain" TargetType="{x:Type TreeViewItem}">
   <Setter Property="HeaderTemplate">
      <Setter.Value>
         <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <Canvas Background="{DynamicResource Terrain_icon}" />
                 <TextBlock Text="{Binding}" />
                 <StackPanel.ContextMenu>
                    <ContextMenu> 
                       <MenuItem Header="Edit..." Click="MyHandler"/> <!-- Error -->
                       <MenuItem Header="Add..."/>
                       <MenuItem Header="Delete"/>
                    </ContextMenu> 
                 </StackPanel.ContextMenu>
             </StackPanel>
          </DataTemplate>
        </Setter.Value>
     </Setter>
 </Style>

C#:

private void InsertTerrainNode(object sender, System.Windows.RoutedEventArgs e)
{
   // Add the new item under the first-level TreeViewItem
   TreeViewItem tvi = myTree.ItemContainerGenerator.ContainerFromItem(myTree.Items[0]) as TreeViewItem;
   TreeViewItem newTerrainNode = new TreeViewItem();
   newTerrainNode.Header = "Terrain";
   newTerrainNode.Style = (Style)this.FindResource("Terrain");
   tvi.Items.Insert(0,newTerrainNode);
}

Upvotes: 1

Views: 4405

Answers (2)

Andy
Andy

Reputation: 30418

Another option is to add an event handler for the MenuItem.Click event to the TreeViewItem as you create it.

private void InsertTerrainNode(object sender, System.Windows.RoutedEventArgs e)
{
    // Add the new item under the first-level TreeViewItem
    TreeViewItem tvi = myTree.ItemContainerGenerator.ContainerFromItem(myTree.Items[0]) as TreeViewItem;
    TreeViewItem newTerrainNode = new TreeViewItem();
    newTerrainNode.Header = "Terrain";
    newTerrainNode.Style = (Style)this.FindResource("Terrain");
    newTerrainNode.AddHandler(MenuItem.Click, OnTreeItemContextMenuClicked);
    tvi.Items.Insert(0,newTerrainNode);
}

private void OnTreeItemContextMenuClicked(object sender, RoutedEventArgs e)
{
    // Handle the ContextMenu item click here
    // e.OriginalSource can be used to get the ContextMenu item clicked if needed.
}

Upvotes: 0

Arsen Mkrtchyan
Arsen Mkrtchyan

Reputation: 50712

Use commands, create a class derived from ICommand, declare in the class that have access to user controles and is accessible in your xaml and bind button with that command. see here for detailes

Upvotes: 1

Related Questions