Я использую MVVM, а пользовательские объекты ICommand предоставляются слоем ViewModel. Один объект ViewModel одновременно может быть прикреплен через свойство DataContext ко многим объектам View (окнам, страницам и т. Д.). В ICommand.CanExecute () я хочу проверить отсутствие ошибок проверки для некоторых элементов управления в View (которые прикреплены к реквизитам ViewModel, имеет значение для конкретной команды виртуальной машины). Одна ViewModel может предоставлять множество команд, каждая из которых имеет собственный набор элементов управления для проверки правильности ошибок. Итак, псевдо-XAML:
<Button.CommandParameter>
<x:Array Type="sys_win:DependencyObject">
<sys_win:DependencyObject>
<reference_to_textbox_or_other_control/>
</sys_win:DependencyObject>
<sys_win:DependencyObject>
<reference_to_textbox_or_other_control/>
</sys_win:DependencyObject>
</x:Array>
</Button.CommandParameter>
Вторая проблема заключается в том, что конкретная команда может быть вызвана элементом управления, который сам является частью DataTemplate для элемента сбора (в моем случае - частью шаблона данных ListBoxItem). Мой шаблонный элемент списка имеет два текстовых поля (привязанных к двум свойствам соответствующей ViewModel) и кнопку, которая вызывает команду ViewModel. Итак, в команде CanExecute () мне нужно проверить наличие ошибок проверки для некоторых элементов управления окнами и двух текстовых полей, которые принадлежат этому элементу списка, а не другим элементам. Приведенный ниже код отлично работает, если я хочу передать свойство ListBoxItem.IsSelected как CommandParameter:
<Button DataContext="{Binding}"
Command="{Binding Path=SwitchCommand}"
CommandParameter="{Binding Path=IsSelected, RelativeSource={
RelativeSource
Mode=FindAncestor,
AncestorType={x:Type ListBoxItem}}}"/>
Но как передать весь (DependencyObject) ListBoxItem в качестве CommandParameter? И как этот ListBoxItem, переданный через {Binding RelativeSource}, может быть смешан с другими текущими элементами управления окна в первом примере кода?
Мне очень жаль, но как я могу добавить ссылки на элементы управления в xaml?
<Button.CommandParameter>
<x:Array Type="sys_win:DependencyObject">
<sys_win:DependencyObject>
<reference_to_textbox_or_other_control/>
</sys_win:DependencyObject>
<sys_win:DependencyObject>
<reference_to_textbox_or_other_control/>
</sys_win:DependencyObject>
</x:Array>
</Button.CommandParameter>
Просто используйте привязку без Путь
:
<Button DataContext="{Binding}"
Command="{Binding Path=SwitchCommand}"
CommandParameter="{Binding RelativeSource=
{RelativeSource
Mode=FindAncestor,
AncestorType={x:Type ListBoxItem}}}"/>
Я не уверен, правильно ли я читаю ваш пример, но, похоже, он немного нарушает принцип MVVM. (Приношу свои извинения, если я неправильно прочитал).
Идея MVVM состоит в том, чтобы отделить модель представления от любой зависимости от сущности XAML / View. Вы нарушаете это, если CommandParameter зависит от пользовательского элемента управления. Что бы я сделал, так это создать свойства состояния в ViewModel и привязать проверки пользовательского управления к этим состояниям, а затем в CanExecute вы можете протестировать значения этих свойств, а не пытаться привязаться к пользовательскому элементу управления.