Silverlight Commands and Button.IsEnabled Property

Topics: Prism v2 - Silverlight 2
Mar 17, 2009 at 6:44 PM
Hi All,

I have noticed a strange behaviour when using the command functionality in Silverlight:

When the  adding the commands:Click.Command and CommandParameter property, the IsEnabled property stops functioning:

<Button Content="Delete" 
    x:Name="Btn_Delete" 
    Margin="0,0,8,0" 
    MinWidth="75" 
    commands:Click.Command="{Binding DeleteCommand}" 
    commands:Click.CommandParameter="{Binding SelectedDepartment}" 
    IsEnabled="false" />

 

 

If I remove the commands: attributes the IsEnabled functions correctly. This behaviour is the same if IsEnabled is bound to a value on my view model too.

Is this a bug? Anyone know of any work arounds?

Thanks,
Mark

Mar 17, 2009 at 11:01 PM

Hi Mark,

 

The Click.Command attached property provided by Composite Application Guidance for WPF & Silverlight requires you to specify an ICommand (generally using DelegateCommand class). In that command you define an Execute and CanExecute method. The CAL relies on this latter method to check if the command can be executed and sets the control's IsEnabled property to the value returned by the CanExecute method.

So, when you use CAL's Click attached property to define commands, the IsEnabled property is set at runtime by the command behavior (more precisely in the UpdateEnabledState method of the CommandBehaviorBase class) which is executed after the isEnabled set in XAML.

 

      protected virtual void UpdateEnabledState()

      {

            ...

            if (this.Command != null)

            {

                TargetObject.IsEnabled = this.Command.CanExecute(this.CommandParameter);

            }
      }

 

You can use the RaiseCanExecuteChanged method from the DelegateCommand class to reevalute the CanExecute method and that will update the isEnabled property of all attached controls.

 

Please let me know if this helps.

 

Matias Bonaventura

http://blogs.southworks.net/matiasb

Mar 18, 2009 at 1:03 PM
Edited Mar 18, 2009 at 1:05 PM
Thanks Matias, this sounds like exactly what I need.
 
I was adjusting the button IsEnabled using a bound property with Notification changes. Where would I set that property in my code? On the dependency property or on the ICommand object?
 
Do you have any small snippets of code (or links to) that show this in action?
 
Many thanks,
Mark
Apr 29, 2010 at 8:29 AM

Hi Matias,

I am having the same problem that Mark is saying.

Can you please more explain the following solution you have provided earlier.

You can use the RaiseCanExecuteChanged method from the DelegateCommand class to reevalute the CanExecute method and that will update the isEnabled property of all attached controls.

  

Thanks

Sheri

Apr 29, 2010 at 3:12 PM

Hi Sherieva,

When you bound a command to a control, it automatically sets the IsEnabled property with the value returned by the command's CanExecute method. That is why when you set the IsEnabled property in XAML, it gets overriden with the command's value.

So, when you bound a command to a control the beheaviour is as follows (independently from the value you set to the IsEnabled property in XAML):

  • If the command's CanExecute method returns false: the control will be disabled.
  • If the command's CanExecute method returns true: the control will be enabled.

WPF automatically requeries the CanExecute method in certain conditions, but if you want to execute it manually you can do something like this:

command.RaiseCanExecuteChanged();

This will query the CanExecute method and update the control's IsEnabled property automatically. 

Matias Bonaventura
http://blogs.southworks.net/matiasb