2009-02-02 24 views
11

У меня есть сценарий, в котором у меня есть элемент управления TreeView WPF, который имеет HierarchicalDataTemplate для своих элементов. Теперь внутри HierarchicalDataTemplate у меня есть Label, а Label имеет ContextMenu с элементом меню для Delete. Элемент меню Delete привязан к команде DeleteCommand, которая является частью класса, который был установлен как DataType из HierarchicalDataTemplate.CommandParameters в ContextMenu в WPF

Теперь я хочу, чтобы передать управление TreeView в CommandParameters из ContextMenu-х Delete MenuItem-х DeleteCommand так, что я могу справиться отбор TreeViewItems на удаление выбранного элемента.

Но если я свяжу CommandParameters как {Binding ElementName=TreeViewName} или что бы там ни было, он всегда равен нулю, если связанный элемент не является свойством в DataContext.

Может ли кто-нибудь помочь мне с решением, потому что я думаю, что я пробовал все возможные вещи, такие как RelativeSource и AncestorType и т. Д., Но всегда имеет значение null. Для меня это выглядит как ограничение или ошибка в структуре.

ответ

17

Проблема заключается в том, что ContextMenu находится в корне своего собственного визуального дерева, поэтому любые привязки RelativeSource.FindAncestor не будут проходить через ContextMenu.

Одним из решений является использование PlacementTarget свойство для установки двухступенчатой ​​связывания с вашего Лейбл:

<Label Tag="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={ 
    x:Type TreeView}}}"> 
    <Label.ContextMenu> 
     <ContextMenu> 
      <MenuItem Header="Delete" Command="{x:Static local:Commands.DeleteCommand}" 
       CommandParameter="{Binding PlacementTarget.Tag, RelativeSource={ 
       RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}"/> 
     </ContextMenu> 
    </Label.ContextMenu> 
</Label> 

Это вполне Hacky, однако. Вам лучше настроить свойство CommandTarget вашего MenuItem на PlacementTarget ContextMenu и иметь обработчик команд на вашем TreeView. Это означает, что вам не придется пропускать TreeView.

+3

Way легко: JoanComasFdz

+1

@JoanComas: после попытки все остальные без успеха (и не понимая, что все это значит с FindAncestors и т. Д.), Ваш способ Easy Way отлично работает! Благодарю. – joedotnot

+2

комментарий @JoanComasFdz действительно помогает. Я могу применить 'CommandParameter =" {Binding} "' просто. – Youngjae

0
<MenuItem Header="..." 
      Command="{Binding Path=...}" 
      CommandParameter="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType={x:Type ContextMenu}}}"> 
</MenuItem> 

ContextMenu.PlacementTarget, это ярлык, где размещается меню. Из Lavel его родительское Treeview доступно.

1
<ContextMenu> 
    <MenuItem Header="Edit Item" 
        Command="{Binding EditItemCommand, Mode=OneWay}" 
        CommandParameter="{Binding Path=UIElement.(views:DataGridView.SelectedItems), RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}" /> 
<ContextMenu> 
Смежные вопросы