2016-09-21 5 views
1

У меня есть следующий макет:Bind MenuItems Команда UserControls DataContext

public class ParentUserControl : UserControl{...} 

<ParentNameSpace:ParentUserControl 
... 
DataContext={Binding MyViewModel ....} 
> 
<TreeView ...>     
<HierarchicalDataTemplate  
     .... > 
       <StackPanel> 
        <StackPanel.ContextMenu> 
         <ContextMenu> 
          <MenuItem Header="item" 
          Command="{Binding DataContext.SomeCommandInMyViewModel, 
           RelativeSource={RelativeSource 
           AncestorType={x:Type ParentUserControl}}}"/> 
         </ContextMenu> 
        </StackPanel.ContextMenu> 
        <TextBlock Text="{Binding Path=Name}"/> 
       </StackPanel> 
      </HierarchicalDataTemplate> 
</TreeView> 

Im пытается вызвать команду UserControls ViewModel внутри контекста TreeViewItem без успеха. Это говорит мне, что ParentUserControl не поддерживается в проекте wpf. Если я изменю AncestorType на UserControl, команда не будет вызвана. Что-то я пропустил?

ответ

0

Это потому, что ContextMenu не является частью визуального дерева. Самый простой способ без изменения кода за это:

Дайте имя ParentUserControl:

<ParentNameSpace:ParentUserControl x:Name="ParentRoot" ... > 

Используйте эту связь:

Command="{Binding Source={x:Reference Name=ParentRoot}, Path=DataContext.SomeCommandInMyViewModel}" 

Update для использования без x:Name атрибута.

Вы можете использовать ContextMenu.PlacementTarget объект, который будет указывать на StackPanel в вашем случае. Тогда вы можете использовать его свойство Tag для доступа к вашей модели просмотра.

<StackPanel Tag="{Binding RelativeSource={RelativeSource AncestorType=ParentNameSpace:ParentUserControl}, Path=DataContext}"> 

И команда:

Command="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.Tag.SomeCommandInMyViewModel}" 
+0

Мой базовый класс является абстрактным и является производным от другого абстрактного класса с одним конструктором параметров, который вызывает: Тип «ParentUserControl» не может иметь атрибут Name. Типы и типы значений без конструктора по умолчанию могут использоваться как элементы в ResourceDictionary. Я не хочу менять базовые классы, есть ли у вас другая идея, чтобы решить эту проблему: /? – Milleu

+0

@Milleu Я обновил ответ. – Sam

+0

Огромное спасибо !, он работает !! :) для моего понимания - я не мог использовать Ancestor внутри ContextMenu, потому что он в другом визуальном дереве (другой процесс или что-то?) - поэтому мне нужно определить тег (или имя) для доступа к ViewModel. У меня есть еще пара HierachicalDataTemplates, я могу определить тег один раз в Treeview или всегда нужно определить тег в элементе owner? (Не успел переместить Tag в Treeview и изменить AncestorType на TreeView) – Milleu

Смежные вопросы