Связывание TreeView с ContextMenu в Xaml - PullRequest
3 голосов
/ 23 марта 2010

Я довольно новичок в 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 голосов
/ 23 марта 2010

Обычно вы не создадите DataTemplate, содержащий TreeViewItem, потому что инфраструктура привязки будет создавать TreeViewItem для вас - все, что вам нужно сделать, это указать, что должно отображаться как content TreeViewItem. Вот почему в найденных вами примерах используются TextBlocks вместо TreeViewItems в DataTemplate.

Я подозреваю, что использование TreeViewItem вместо TextBlock приводит к чрезмерному отступу, потому что у вас есть (вручную созданный) TreeViewItem в вашем DataTemplate (который имеет один уровень отступа) внутри другого (автоматического) 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>

Между прочим, для TreeViews обычно используется HierarchicalDataTemplate, а не обычный DataTemplate, потому что это позволяет использовать несколько уровней элементов через свойство HierarchicalDataTemplate.ItemsSource. Это может не потребоваться в вашем сценарии, хотя.

...