Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is CanExecute called?

Tags:

c#

.net

wpf

In the demo, I have a button to toggle a bool field isAsking. I create a command which can execute only when isAsking==true.

Once I press the Toggle button, okButton.IsEnable changes immediately, which indicates the command finds the change of isAsking.

I feel very confused why the command object notices the change of a field. When CanExecute will be called?

Although writting WPF application for some time, I'm new to WPF Command. Please give an explanation to this case and if possible, point out some related articles or blogs (I've already read too many articles talking about cut/paste command).

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"         x:Class="WpfApplication1.MainWindow"         Title="MainWindow" Height="350" Width="525" x:Name="mainWindow" >     <StackPanel>         <Button Name="okButton" Content="Ok" />         <Button Content="Toggle"  Click="Button_Click_1"/>     </StackPanel> </Window> 

Code-behind:

public partial class MainWindow : Window {     private bool isAsking;      public MainWindow()     {         InitializeComponent();          CommandBinding cb = new CommandBinding();         cb.Command = okCommand;         cb.CanExecute += CanOKExecute;         cb.Executed += cb_Executed;         mainWindow.CommandBindings.Add(cb);         okButton.Command = okCommand;     }      private RoutedCommand okCommand = new RoutedCommand("ok", typeof(MainWindow));       void cb_Executed(object sender, ExecutedRoutedEventArgs e)     {             }      void CanOKExecute(object sender, CanExecuteRoutedEventArgs e)     {         e.CanExecute = isAsking;     }      private void Button_Click_1(object sender, RoutedEventArgs e)     {         isAsking = !isAsking;     } } 
like image 738
Gqqnbig Avatar asked Jan 12 '13 15:01

Gqqnbig


People also ask

What is CanExecute?

Defines the method that determines whether the command can execute in its current state.

Can you execute in WPF?

Commands in WPF are created by implementing the ICommand interface. ICommand exposes two methods, Execute, and CanExecute, and an event, CanExecuteChanged. Execute performs the actions that are associated with the command. CanExecute determines whether the command can execute on the current command target.

Which method of ICommand will let you know if the command can be executed or not?

CanExecute will determine whether the command can be executed or not. If it returns false the button will be disabled on the interface.

What is WPF ICommand?

The ICommand interface is the code contract for commands that are written in . NET for Windows Runtime apps. These commands provide the commanding behavior for UI elements such as a Windows Runtime XAML Button and in particular an AppBarButton .


2 Answers

The technical answer is that CanExecute will be invoked whenever the CommandManager.RequerySuggested event is raised. According to the documentation, this will be...

...when the CommandManager detects conditions that might change the ability of a command to execute.

In practical terms, this just means that you don't need to worry about when CanExecute is called: WPF will invoke it when it thinks it is appropriate, and in my experience this will almost always cover your requirements.

The exception to this is if you have a background task that will cause CanExecute to change it's return value based on something that is not triggered by the UI. In this scenario, you may need to manually force the WPF runtime to re-query CanExecute which you can do by calling CommandManager.InvalidateRequerySuggested

like image 115
Steve Greatrex Avatar answered Sep 29 '22 04:09

Steve Greatrex


I try to search for "the CommandManager detects conditions" and reach this exellent article.

By examining .NET Framework source code, the author finds that the CommandManager doesn't detect conditions by itself, rather than when Keyboard.KeyUpEvent, Mouse.MouseUpEvent, Keyboard.GotKeyboardFocusEvent, or Keyboard.LostKeyboardFocusEvent occurs, it will reevaluate CanExecute method.

The article includes other information, but the above part has been enough for me.

like image 44
Gqqnbig Avatar answered Sep 29 '22 03:09

Gqqnbig