Привязки ComboBox, Button & ICommand (MVVM-ish) - PullRequest
3 голосов
/ 09 февраля 2012

Учитывая следующее XAML ...

<ComboBox x:Name="advisoriesComboBox"
  DisplayMemberPath="Name" 
  ItemsSource="{Binding Path=Advisories}" 
  SelectedItem="{Binding Path=SelectedAdvisory}" />

<Button Command="{Binding Path=AddAdvisoryCommand}"
  CommandParameter="{Binding ElementName=advisoriesComboBox, Path=SelectedItem}"
  CommandTarget="{Binding ElementName=advisoriesComboBox}"
  Content="Add..." />

Я ищу способ связать ComboBox, Button и Command таким образом, чтобы при изменении значения ComboBox в команде вызывался CanExecute. Чистый эффект от того, что я хочу, - это возможность включать и отключать кнопку в зависимости от того, какой элемент выбран в списке, и я предпочел бы сделать это с помощью интерфейса ICommand.

Я делал это в прошлом, используя свойство «SelectedAdvisory» на виртуальной машине и вручную вызывая RaiseCanExecuteChanged для объектов команды (я использую экземпляры DelegateCommand из PRISM v4), но я уверен, что есть более качественный и чистый инструмент. способ сделать это, используя только XAML.

Спасибо.

РЕДАКТИРОВАТЬ: Кроме того, есть ли более простой способ ссылки на ComboBox с помощью кнопки? Я пытался использовать RelativeSource PreviousData, но не смог заставить его работать, поэтому использование x:Name.

Еще раз спасибо.

Ответы [ 2 ]

2 голосов
/ 09 февраля 2012

Я бы сделал все в ViewModel, мне кажется, лучше всего, когда дело доходит до модульного тестаошибки.

1 голос
/ 09 февраля 2012

То, что вы сейчас настроили, я бы сделал. Если команда может быть выполнена или нет, это бизнес-правило, то есть оно должно обрабатываться из ViewModel, а не View.

Единственное, что я делаю, - это повышение CanExecuteChanged() в событии PropertyChange вашей ViewModel вместо set метода SelectedAdvisory

void MyViewModel()
{
    this.PropertyChanged += MyViewModel_PropertyChanged;
}

void MyViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    switch(e.PropertyName)
    {
        case "SelectedAdvisory":
            ((DelegateCommand)AddAdvisoryCommand).RaiseCanExecuteChanged();
            break;
    }
}

Я предпочитаю по возможности не использовать логику в моих методах получения / установки, а использование события PropertyChanged позволяет мне видеть все, что происходит, когда свойства изменяются в одном месте.

Конечно, если вы используете RelayCommand вместо DelegateCommand, вам не нужно вручную повышать CanExecuteChanged() при изменении свойств, поскольку это происходит автоматически.

Вы также можете немного упростить свой XAML, предоставив обоим общим DataContext. Button вообще не должен ссылаться на ComboBox.

<ComboBox
  DisplayMemberPath="Name" 
  ItemsSource="{Binding Path=Advisories}" 
  SelectedItem="{Binding Path=SelectedAdvisory}" />

<Button Command="{Binding Path=AddAdvisoryCommand}"
  CommandParameter="{Binding SelectedAdvisory}"
  Content="Add..." />
...