4

鉴于以下 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 的值发生变化时,就会在 Command 上调用 CanExecute。我想要的最终效果是能够根据在列表中选择的项目启用和禁用按钮,我更喜欢使用 ICommand 界面来执行此操作。

我过去通过使用 VM 上的“SelectedAdvisory”属性并在命令对象上手动调用 RaiseCanExecuteChanged 来完成此操作(我使用的是 PRISM v4 中的 DelegateCommand 实例),但我确信有更好、更清洁的方法来做这仅使用 XAML。

谢谢。

编辑:此外,是否有更简单的方法可以从 Button 引用 ComboBox?我尝试使用 RelativeSource PreviousData 但无法使其工作,因此使用x:Name.

再次感谢。

4

2 回答 2

2

我会在视图模型中做所有事情,在我看来,在单元测试方面是最好的

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

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

虚拟机

private bool CanAddExecute()
{
   return this.SelectedAdvisory != null; 
}

private void AddExecute()
{
   if(!CanAddExecute())
      return;

   //do here what you want, your information for the selected item is in this.SelectedAdvisory 
}

代码是手写的,所以可能会有一些错误。

于 2012-02-09T14:14:37.273 回答
1

你现在设置的就是我要做的。该命令是否可以执行是一个业务规则,这意味着它应该从 处理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;
    }
}

如果可能的话,我更喜欢将逻辑排除在我的 getter/setter 之外,并且使用该PropertyChanged事件可以让我看到当属性在一个位置发生变化时发生的一切。

当然,如果您使用的是 aRelayCommand而不是 aDelegateCommand您不需要手动提高CanExecuteChanged()when 属性更改,因为它会自动执行。

您还可以稍微简化您的 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..." />
于 2012-02-09T14:00:44.737 回答