Я использую шаблон команды с (между прочим) контекстным меню в TreeViewItem, который использует HierarchicalDataTemplates. MainWindowViewModel (статический ресурс для окна) имеет свойства, которые выставляют одноэлементные объекты, которые, в свою очередь, имеют свойства, которые представляют команды. Я могу выполнить команду очень хорошо, но некоторые из команд должны передать DataContext TreeViewItem как CommandParameter.WPF Databinding ContextMenuItem's CommandParameter для DataContext TreeViewItem
Вот пример: Один узел дерева имеет элемент ItemsSource, связанный с ObservableCollection отдельных объектов AnalysisMain. Каждый из результирующих поднодов имеет ContextMenu (с DataContext, связанным с AnalysisController), который имеет (помимо прочего) Remove MenuItem. Свойство Remove MenuItem Command связано с командой CommandRemove объекта SingleControlController (и он выполняется просто отлично). Но это также требует, чтобы CommandParameter привязывался к объекту AnalysisMain, который служит DataContext для подузлов в дереве. Я попытался с помощью RelativeSource с AncestorType, установленным в TreeViewItem и Путь установлен в DataContext:
<HierarchicalDataTemplate DataType="{x:Type vmAnalysis:AnalysisMain}">
<WrapPanel Orientation="Horizontal">
<Image Source="Analysis\Icon_Analysis_Main_16_Normal.png" Margin="0,0,2,0" Width="16"/>
<TextBlock Text="{Binding TreeViewTitle}">
<TextBlock.ContextMenu>
<ContextMenu DataContext="{StaticResource mainWindowViewModel}">
<MenuItem Header="Remove" Command="{Binding Path=AnalysisController.CommandRemove}"
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}, AncestorLevel=4}, Path=DataContext}">
</MenuItem>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</WrapPanel>
</HierarchicalDataTemplate>
без AncestorLevel набора, когда я открываю ContextMenu, я получаю следующее в окне Output:
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.TreeViewItem', AncestorLevel='4''. BindingExpression:Path=DataContext; DataItem=null; target element is 'MenuItem' (Name=''); target property is 'CommandParameter' (type 'Object')
Я пробовал несколько значений для AncestorLevel безрезультатно.
Изучив визуальное дерево в инспекторе Христиана Мозера WPF, я не вижу контекстного меню в визуальном дереве. Хотя TreeViewItem показывает объект DataContext. Мне просто нужен способ «ориентироваться» на него, чтобы привязываться к нему.
В качестве альтернативы, я попытался оставить ContextMenu DataContext один и настройки команды Binding Source-х, чтобы указать назад к AnalysisController. Это также работает для выполнения команды, но я не способен связываться с DataContext в TreeViewItem для в CommandParameter:
<ContextMenu>
<MenuItem Header="Remove" Command="{Binding Source={StaticResource mainWindowViewModel}, Path=AnalysisController.CommandRemove}"
CommandParameter="{Binding Source={RelativeSource Self}, Path=DataContext}">
</MenuItem>
</ContextMenu>
Я также попытался просто использовать CommandParameter = «{Binding}», который также не работает , (В обоих случаях я просто получаю null в качестве параметра. В окне вывода не записывается предупреждение/ошибка.) EDIT: для кого-либо еще с этой проблемой второй вариант был обречен с самого начала, потому что я ошибочно положил Source = {RelativeSource Self}, который будет ссылаться на MenuItem, а не на TreeViewItem. Однако изменение этого параметра с AncestorType/AncestorLevel не имеет значения.
я могу ошибаться о точной ошибки связанной к 'CommandParameter', на самом деле параметр имеет значение null внутри' CanExecute' (что означает, что Binding не работает), но внутри 'Execute' callback, параметр передается OK. Для ранее опубликованного кода вы можете попробовать посмотреть в окне «Выход», чтобы узнать, есть ли там какая-либо ошибка. –
Я проверил (переопределить CanExecute, чтобы всегда возвращать true), и параметр по-прежнему равен нулю. – Tim