如何从TreeView ContextMenu获取MenuItem单击事件

时间:2009-07-23 07:26:51

标签: wpf treeview contextmenu

我将TreeViewItems插入到TreeView控件中,并在插入时为每个控件设置样式。我正在分配不同的样式(在XAML中预定义),具体取决于我要插入的节点类型(TreeViewItem)。一些样式包括ContextMenu。

我的问题是我无法在MenuItems上使用Click =“MyHandler”;我收到错误“root元素需要x:Class属性来支持XAML文件中的事件处理程序。”显然,Style块中的元素都不是根元素。

任何建议都非常感谢。

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

2 个答案:

答案 0 :(得分:1)

使用命令,创建一个从ICommand派生的类,在类中声明可以访问用户控制的类,并且可以使用该命令在xaml和bind按钮中访问。请参阅here了解详细信息

答案 1 :(得分:0)

另一个选项是在创建MenuItem.Click时为TreeViewItem添加事件处理程序。

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