WPF CommandParameter binding not updating

ColinE picture ColinE · Jun 22, 2010 · Viewed 7.2k times · Source

I am trying to use Command and CommandParameter binding with Buttons in a WPF application. I have this exact same code working just fine in Silverlight so I am wondering what I have done wrong!

I have a combo box and a button, where the command parameter is bound to the combobox SelectedItem:

<Window x:Class="WPFCommandBindingProblem.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <StackPanel Orientation="Horizontal">
        <ComboBox x:Name="combo" VerticalAlignment="Top" />
        <Button Content="Do Something" Command="{Binding Path=TestCommand}"
                CommandParameter="{Binding Path=SelectedItem, ElementName=combo}"
                VerticalAlignment="Top"/>        
    </StackPanel>
</Window>

The code behind is as follows:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        combo.ItemsSource = new List<string>(){
            "One", "Two", "Three", "Four", "Five"
        };

        this.DataContext = this;

    }

    public TestCommand TestCommand
    {
        get
        {
            return new TestCommand();
        }
    }

}

public class TestCommand : ICommand
{
    public bool CanExecute(object parameter)
    {
        return parameter is string && (string)parameter != "Two";
    }

    public void Execute(object parameter)
    {
        MessageBox.Show(parameter as string);
    }

    public event EventHandler CanExecuteChanged;

}

With my Silverlight application, as the SelectedItem of the combobox changes, the CommandParameter binding causes the CanExecute method for my command to be re-evaluated with the currently selected item and the button enabled state is updated accordingly.

With WPF, for some reason, the CanExecute method is only invoked when the binding is created when the XAML is parsed.

Any ideas?

Answer

Goblin picture Goblin · Jun 22, 2010

You need to tell WPF that CanExecute can change - you can do this automatically in your TestCommand class like this:

public event EventHandler CanExecuteChanged
{
    add{CommandManager.RequerySuggested += value;}
    remove{CommandManager.RequerySuggested -= value;}
}

WPF will then ask CanExecute everytime a property changes in the view.