在Xaml中将TreeView与ContextMenu绑定

Mic*_*oll 3 wpf treeview xaml binding contextmenu

我对Xaml很新,需要一些建议.

TreeView应绑定到分层对象结构.TreeView应该有一个上下文菜单,该菜单特定于每个对象类型.

我尝试过以下方法:

<TreeView>
  <TreeView.Resources>
    <DataTemplate x:Key="RoomTemplate">
      <TreeViewItem Header="{Binding Name}">
        <TreeViewItem.ContextMenu>
          <ContextMenu>
            <MenuItem Header="Open" />
            <MenuItem Header="Remove" />
          </ContextMenu>
        </TreeViewItem.ContextMenu>
      </TreeViewItem>
    </DataTemplate>
  </TreeView.Resources>

  <TreeViewItem Header="{Binding Name}" Name="tviRoot" IsExpanded="True" >

  <TreeViewItem Header="Rooms"  
                ItemsSource="{Binding Rooms}"
                ItemTemplate="{StaticResource RoomTemplate}">
    <TreeViewItem.ContextMenu>
      <ContextMenu>
        <MenuItem Header="Add room"></MenuItem>
      </ContextMenu>
    </TreeViewItem.ContextMenu>
  </TreeViewItem>
</TreeViewItem>
Run Code Online (Sandbox Code Playgroud)

但是使用此标记时,行为符合预期,但子项(房间)缩进太多.

无论如何,我能找到的所有结果样本都在DataTemplate中使用TextBlock而不是TreeViewItem,但是想知道如何在那里集成ContextMenu.

ito*_*son 8

您通常不会创建包含TreeViewItem的DataTemplate,因为绑定基础结构将为您创建TreeViewItem - 您的所有DataTemplate需要做的是指定应显示为TreeViewItem 的内容.这就是为什么你发现的样本在DataTemplate中使用TextBlocks而不是TreeViewItems.

我怀疑使用TreeViewItem而不是TextBlock会导致过度缩进,因为你的DataTemplate中有一个(手动创建的)TreeViewItem(它会产生一个级别的缩进),而另一个(自动)TreeViewItem会导致另一个级别的缩进.因此,使用TextBlock而不是TreeViewItem应该可以解决这个问题.集成ContextMenu应该不是问题,因为TextBlock也具有ContextMenu属性.

因此,您应该能够按如下方式更改DataTemplate:

<DataTemplate x:Key="RoomTemplate">
  <TextBlock Text="{Binding Name}">
    <TextBlock.ContextMenu>
      <ContextMenu>
        <MenuItem Header="Open" />
        <MenuItem Header="Remove" />
      </ContextMenu>
    </TextBlock.ContextMenu>
  </TextBlock>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)

顺便提一下,对于TreeViews,通常使用HierarchicalDataTemplate而不是普通的DataTemplate,因为这允许通过HierarchicalDataTemplate.ItemsSource属性实现多级别的项目.但是,在您的方案中可能不需要这样做.