Search code examples
c#.netwpficommand

Button not enabled even after providing CommandParameter in WPF


I created a button whose commandparameter is set and command using a class that implements ICommand interface. But my button is disabled. Why is that? I got this code from here: ICommand is like a chocolate cake

<Window x:Class="ICommand_Implementation_CSharp.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:ICommand_Implementation_CSharp"
    Title="MainWindow" Height="350" Width="525">
<Grid>      
    <Grid>
        <Grid.Resources>
            <local:HelloWorldCommand x:Key="hwc"  />
        </Grid.Resources>

        <Button Command="{StaticResource hwc}" CommandParameter="Hello" 
                Height="23" HorizontalAlignment="Left" Margin="212,138,0,0" 
                Name="Button1" VerticalAlignment="Top" Width="75">Button</Button>
    </Grid>
</Grid>

and my class is

class HelloWorldCommand:ICommand
{
    public bool CanExecute(object parameter)
    {
        return parameter != null;
    }

    public event EventHandler CanExecuteChanged;

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

Solution

  • Well, this is very-very simple implementation of ICommand.

    As @JleruOHeP says, partially problem can be solved by swapping setters of Command and CommandParameter. But this is ugly way, because you have to remember the sequence every time.

    More correct way is to tell CommandManager to re-query states of command:

    public class HelloWorldCommand : ICommand
    {
        public bool CanExecute(object parameter)
        {
            return parameter != null;
        }
    
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
    
        public void Execute(object parameter)
        {
            MessageBox.Show(parameter.ToString());
        }
    }
    

    Now the sequence of setters is indifferent.
    To understand how CommandManager works, you can read this nice article from Josh Smith.