Given the following 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..." />
I am looking for a way to bind the ComboBox, Button and Command in such a way that when the value of the ComboBox changes, CanExecute is called on the Command. The net effect of what I want is to be able to enable and disable the Button based upon which item is selected in the list and I would prefer to do this using the ICommand interface.
I have done this in the past by using the “SelectedAdvisory” property on the VM and manually calling RaiseCanExecuteChanged on the command objects (I am using DelegateCommand instances from PRISM v4), but I feel sure that there is a better and cleaner way to do this using XAML only.
Thanks.
EDIT: Additionally, is there a simpler way to reference the ComboBox from the Button? I tried using RelativeSource PreviousData but could not get it to work, hence the usage x:Name.
Thanks again.
What you have setup now is what I would do. If the command can execute or not is a business rule, which means it should be handled from the
ViewModel, not theView.The only difference is I make is to raise the
CanExecuteChanged()in thePropertyChangeevent of your ViewModel, instead of thesetmethod ofSelectedAdvisoryI prefer to keep logic out of my getters/setters if possible, and using the
PropertyChangedevent lets me see everything that happens when properties change in one location.Of course, if you’re using a
RelayCommandinstead of aDelegateCommandyou don’t need to manually raise theCanExecuteChanged()when properties change since it does it automatically.You can also simplify your XAML a bit providing both share the same
DataContext. TheButtonshouldn’t need to reference theComboBoxat all.