在Xaml中绑定带有上下文菜单的TreeView

3

我很新于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>

但是使用这种标记时,行为是按预期进行的,但子项(房间)缩进太多。

无论如何,我能找到的所有绑定示例都使用TextBlock而不是TreeViewItem在DataTemplate中,但想知道如何在那里集成ContextMenu。

1个回答

8
通常情况下,您不会创建一个包含TreeViewItem的DataTemplate,因为绑定基础结构将为您创建TreeViewItem - 您的DataTemplate只需要指定应作为TreeViewItem的内容显示的内容即可。这就是为什么您找到的示例在DataTemplate中使用TextBlock而不是TreeViewItem的原因。
我怀疑使用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>

顺便提一下,对于TreeView来说,通常使用HierarchicalDataTemplate而不是普通的DataTemplate,因为这样可以通过HierarchicalDataTemplate.ItemsSource属性实现多级项目。虽然在您的情况下可能并非必需。


太好了,成功了!我也在使用HierarchicalDataTemplate。但是我该如何将一些固定的(非绑定的)子项添加到数据绑定的项模板中呢?例如:
房间
房间1
窗户
窗户1 门 其中只有房间1和窗户1是数据绑定的?
- Michael Stoll
所以你想插入额外的固定节点?我认为你可以通过回到TreeViewItem的方法来实现:你的数据模板将是一个带有固定标题的TreeViewItem,其ItemsSource绑定到HDT的上下文,例如<HDT><TreeViewItem Header="Rooms" ItemsSource="{Binding}" /></HDT>。虽然没有经过测试!如果这不起作用,你可能想要将其发布为一个新问题,因为这将很可能得到更多的关注,因此会得到更好的答案 - 只是一个建议! - itowlson
不行,那样做不了。我会发布一个新问题。 - Michael Stoll

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接