WPF: Как передать весь элемент управления как CommandParameter через XAML? - PullRequest
8 голосов
/ 14 августа 2010

Я использую MVVM, и пользовательские объекты ICommand предоставляются слоем ViewModel.Один объект ViewModel одновременно может быть присоединен через свойство DataContext ко многим объектам View (окнам, страницам и т. Д.).В ICommand.CanExecute () я хочу проверить отсутствие ошибок проверки для некоторых элементов управления в View (которые прикреплены к реквизитам ViewModel, существенным для конкретной команды VM).Одна 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>

Ответы [ 2 ]

27 голосов
/ 14 августа 2010

Просто используйте привязку без Path:

<Button DataContext="{Binding}" 
        Command="{Binding Path=SwitchCommand}"
        CommandParameter="{Binding RelativeSource=
                                   {RelativeSource
                                    Mode=FindAncestor,
                                    AncestorType={x:Type ListBoxItem}}}"/>
1 голос
/ 14 августа 2010

Я не уверен, правильно ли я читаю ваш пример, но, похоже, он немного нарушает принцип MVVM. (Мои извинения, если я прочитал это неправильно).

Идея MVVM состоит в том, чтобы отделить модель представления от любой зависимости от сущности XAML / View. Вы ломаете это, когда CommandParameter зависит от пользовательского контроля. Я хотел бы создать свойства состояний в ViewModel и связать проверки usercontrol с этими состояниями, а затем в CanExecute вы можете проверить значения этих свойств, а не пытаться связать их с usercontrol.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...