button click using command ^ events, briefly

As illustrated in other blog posts (like http://bigblog.tanbin.com/2013/06/routed-events-learning-notes.html), a button click can be connected to (via xaml) a regular instance method in the xaml class (code behind), provided the method is an event handler. In this implementation, we are using a CLR event, not really routed event.

This simple design draws criticism such as tight coupling etc. There’s an alternative. Using commands, we can refactor to meet the same requirement. [[wpf succinctly]] has a simple example of this refactor.

Another book says — “In WPF and Silverlight, there are two ways to respond to user interaction: with events and with commands. Most controls will support both of these methods of interaction, but it seems more common for events to be exposed.

Advertisements

WPF Commanding components – fluff^barebones

Q: Key players in a typical commanding set-up?

The 4 key players identified in the MSDN article is the perspective from the builtin commands (RoutedCommand). I’d rather /unlearn/ the whole thing because I prefer a minimalist perspective.

1) ICommand (#1) is the single most important component. Together with the ViewModel (#2) and the xaml, it can meet many simple commanding requirements, without the CommandSource, CommandTarget, CommandBinding crap.

2) For a slightly more complex requirement, I feel these are the key players —
– ICommand instance
– command source instance
– ViewModel instance
– xaml (and code behind it)
? routed command? LG2. This is more advanced. A lot of xaml commands are much simpler
? command binding? LG2 See other posts.
? command target? LG2. Needed in RoutedCommand cases.
? CanExecuteChanged? not always needed
? CanExecute() can simply return true always.
? Execute() can simply hold the business logic rather than delegating to something else

CanExecute and CanExecuteChanged provide lots of flexibility, which is often unneeded in simple requirements.

ViewModel is relevant because there’s good reason to move logic out of the code behind, into … usually into the VM. Therefore the real command logic lives in the VM classes. Specifically, the Execute() logic often involves the VM. Ditto CanExecute()

http://relentlessdevelopment.wordpress.com/2010/03/30/simplified-mvvm-commanding-with-delegatecommand/ has a simple example. It illustrates xaml, view model, delegate command… It deliberately defines CanExecute and CanExecuteChanged, but never uses them!

delegate command with(out) CommandManager

Now I feel you can implement a basic delegate command with or without CommandManager. (My sample wpf application description is in another blog post.)

A) The original RelayCommand by Josh Smith uses CommandManager. With CommandManager, we developers don’t need to add InvalidateRequerySuggested() after some VM state change, since CommandManager will take care of that.

One consequence is, the CommandManager fires a hell lot of activity via (static) event CommandManager.RequerySuggested. Since our custom CanExecuteMyCommand() callback is in the inv list, it gets called every time.

B) Some prefer a home-grown delegate command without CommandManager. Event firing is better understood and less opaque than with CommandManager. However, we do need to remember to add something like MyCommand.RecheckStatus() in many places.

Here’s my guess — Since the inv list is no longer provided by CommandManager, we must provide it in our delegate command class. There’s one inv list per command instance. By contrast, the CommandManager has one application-wide inv list for all the command instances. The inv list is behind the application-wide static event.

who subscribes to the ICommand.CanExecuteChanged event?

I put a breakpoint on the event add{} and found out exactly which object is subscribing to the ICommand.CanExecuteChanged event.

 

————— wpf_proj_readme.txt —————–

This entire wpf app has a single VM. Among other things it defines a bool method vm.CanExecuteSave(). Note VM isn’t subclass of ICommand; TanBinRelayCommand is. It’s just a generic relay command class.

 

Xaml has a textbox and a Save button. Textbox is data-bound to a string property in VM; button to an ICommand property in VM – consistency. Entire xaml uses the VM as the only data context, so all data bindings are between the xaml (visuals) and the VM (properties) – consistency.

 

This vm.CanExecuteSave() method (wrapped in a delegate) is passed in when instantiating TanBinRelayCommand, the Command object behind the button. Therefore button “dimmer” is connected to vm.CanExecuteSave() method. Later at runtime the button is dimmed when CanExecuteSave becomes false.

———————————————————–

 

Question is how does the runtime know when to requery CanExecuteSave(). The solution, as a standard pattern, is event subscription. Specifically, the button adds this.OnCanExecuteChanged() method into the inv list of the ICommand.CanExecuteChanged event.   But when is this method added into the inv list? At xaml initialization, HookCommand() performs this registration.

 

    abstract public class TanBinRelayCommand: ICommand{

        private Action methodToExecute;

        private Func<bool> isEnabled;

 

        public TanBinRelayCommand(Action methodToExecute, Func<bool> isEnabled)

        {

            this.methodToExecute = methodToExecute;

            this.isEnabled = isEnabled;

        }

        #region ICommand members

        ///

        /// who subscribes to this event? I think the command binding (or other objects in the xaml)

        ///

        bool ICommand.CanExecute(object obj) {

            if (this.isEnabled == null) return true;

           

            return this.isEnabled.Invoke();

        }

        void ICommand.Execute(object obj)

        {

            if (this.methodToExecute != null)

                this.methodToExecute.Invoke();

        }

        abstract public event EventHandler CanExecuteChanged;

       

CommandBinding – is associated with command target

From http://msdn.microsoft.com/en-us/library/system.windows.input.commandbinding.aspx, I get the feeling that a command binding (CB) instance is associated with a command target. I’d say the CB instance is injected into the command target object, which is usually a visual control.

(This seems to echo the very common and essential data binding in xaml, where the binding object is injected into the target, not the source.)

I also get the feeling that CB is used only for routed command. If that’s the case, I feel this is a slightly advanced feature. For an initial grip on the commanding paradigm, some students should probably skip this CB topic. [[wpf succinctly]] doesn’t mention command binding or command target. My delegate command implementations don’t use CB either.

I understand command binding is crucial in routed commands, since the bubble or tunnel will scan the containment hierarchy stopping at a command binding. The builtin WPF commands are all RoutedCommands.

2 technical motivations for inventing WPF commanding

When WPF creators came up with the command infrastructure, they had some competing designs, motivations, trade-off etc. http://msdn.microsoft.com/en-us/library/ms752308.aspx pointed out 2 major driving forces. Here’s my wording, not the original wording

1) 1:Multiple
2) enable/disable the Multiple CommandSources at once.

Various authors also touched on these 2 concepts among other concepts. I find it extremely insightful to single out these 2 primary purposes.

Let me elaborate a bit ….

many-to-1 relation — at heart of wpf commanding

To a beginner (like me) wpf commanding has a many-to-1 entity relationship at its core. This m:1 is highlighted in numerous wpf tutorials.

m:1 means 1 logical “task” mapping to multiple physical “controls”. (Note it’s Never many-to-many.) Best example is a simple print (or Save or Close) task mapped to a shortcut  key combination, a button, a menu bar item, a context menu item etc.

It may be slightly imprecise to call them “controls”, but this terminology is nice and simple. Let’s not play language lawyers. Strictly, the shortcut key is actually a KeyGesture instance, and a kind of “command source”. Indeed, Command-source is the technical term — rather abstract.

When you first expand your design from 1:1 to 1:2, adding a 2nd control, you may do a bit of harmless copy-paste. When you expand to 1:m, you need more serious OO modelling and abstraction. The OO abstraction chosen by WPF creators is the commanding infrastructure, an object-oriented solution. (As mentioned in
http://bigblog.tanbin.com/2012/04/gui-swing-etc-needs-more-object.html, GUI systems often feature powerful, elegant design patterns.) The commanding pattern addresses the configuration, and the binding — the glue-up, the hook-up, the plumbing between source (and target) “controls” on one hand and task execution logic on the other — the m:1 mapping.

As explained in THE msdn article (http://msdn.microsoft.com/en-us/library/ms752308.aspx), a command binding instance connects 3 kinds of things — command / source / target. The 1:m is “command 1: many Sources” [1]. The target is slightly less important to a beginner.

[1] a KeyGesture instance is also a command source.

Is an ICommand instance stateful? Usually no

A typical ICommand instance is typically stateless.I think many implementations would keep it stateless.

 I feel good de-coupling dictates that ICommand should not reference any view, or anything in the xaml (i.e. any visual objects on the screen). So how does the Execute() method work? Usually by raising events. Alternatively, if you choose to actually implement Execute() with real logic, then Execute would need to access some objects, which are often passed in as argument. Still stateless.

Q: What state does an instance of this Class represent? (This generic question often gives insight into any Class.)
A: the enabled/disabled Boolean status of a “logical” operation. The operation can come from multiple user input controls, such as keyboard shortcut (KeyGesture), a button, a menu item, a context menu item. When the status is disabled, all these controls become dimmed.

The ICommand interface defines only a few members. The bool CanExecute() method feels like a read-only Boolean property. I feel this Boolean state is about the ONLY state there is in a command Instance.

By the way, a command Source object is also a stateful instance. See content of ICommandSource.

a WPF "command" is … a princess

(Consider also RequerySuggested)

Q: what is a command in wpf?

Best answer is found in the ICommand interface — a command Instance must offer
1) an Execute() method,
2) a capability-query method CanExecute(). It’s also a status-query method.
3) an event notification scheme, in the form of an event-pseudo-field CanExecuteChanged.

Today let’s focus on 3). I believe this event enables the infrastructure to adjust the appearance of the buttons/menus linked to the command

3 describes 2; 2 describes 1.

I say CanExecuteChanged is a “scheme” because the underlying plumbing is non-trivial to a java/c++ guy, but plain vanilla to a c# guy. To understand this scheme, we must first get a good grip on event-pseudo-field — a bunch of callback functors. See http://bigblog.tanbin.com/2011/09/an-event-pseudo-field-wrapper-over.html.

In the CanExecuteChanged context, when the command’s status switches between Enabled/Disabled or between CanExecute and CannotExecute, this event is raised. An (ordered) list of callbacks get invoked.

Each callback holds 2 pointers, one referencing a callback method, the other referencing its host object. Some people say …
Each callback holds 2 pointers, one referencing a Receiver object, the other referencing a method therein.

One of the things each callback does is to query the command instance via CanExecute(). Therefore, the CanExecuteChanged event is an invitation to “call me for my current status”. Command is a young princess with an army of suitors. They want to know when she’s available for dating. Once a while she sends an open invitation to “call my hotline to ask for my availability” — the princess has a dedicated hotline (CanExecute) to answer that query.