Monday, October 24, 2011

Commands In WPF

Commands In WPF
Commanding is an input mechanism in Windows Presentation Foundation (WPF) which provides input handling at a more semantic level than device input. Examples of commands are the Copy, Cut, and Paste operations found on many applications.

The simplest way to use a command in WPF is to use a predefined RoutedCommand from one of the command library classes; use a control that has native support for handling the command; and uses a control that has native support for invoking a command. The Paste command is one of the predefined commands in the ApplicationCommands class. The TextBox control has built in logic for handling the Paste command. And the MenuItem class has native support for invoking commands.
The following example shows how to set up a MenuItem so that when it is clicked it will invoke the Paste command on a TextBox, assuming the TextBox has keyboard focus

Four Main Concepts in WPF Commanding
1. The command is the action to be executed.
2. The command source is the object which invokes the command.
3. The command target is the object that the command is being executed on.
4. The command binding is the object which maps the command logic to the command.

Commands
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.
CanExecuteChanged is raised if the command manager that centralizes the commanding operations detects a change in the command source that might invalidate a command that has been raised but not yet executed by the command binding.
The WPF implementation of ICommand is the RoutedCommand class and is the focus of this overview.
The main sources of input in WPF are the mouse, the keyboard, ink, and routed commands. The more device-oriented inputs use a RoutedEvent to notify objects in an application page that an input event has occurred. A RoutedCommand is no different. The Execute and CanExecute methods of a RoutedCommand do not contain the application logic for the command, but rather they raise routed events that tunnel and bubble through the element tree until they encounter an object with a CommandBinding. The CommandBinding contains the handlers for these events and it is the handlers that perform the command. For more information on event routing in WPF, see Routed Events Overview.
The Execute method on a RoutedCommand raises the PreviewExecuted and the Executed events on the command target. The CanExecute method on a RoutedCommand raises the CanExecute and PreviewCanExecute events on the command target. These events tunnel and bubble through the element tree until they encounter an object which has a CommandBinding for that particular command.
WPF supplies a set of common routed commands spread across several classes: MediaCommands, ApplicationCommands, NavigationCommands, ComponentCommands, and EditingCommands. These classes consist only of the RoutedCommand objects and not the implementation logic of the command. The implementation logic is the responsibility of the object on which the command is being executed on.

Command Sources
A command source is the object which invokes the command. Examples of command sources are MenuItem, Button, and KeyGesture.
Command sources in WPF generally implement the ICommandSource interface.

Command Binding
A CommandBinding associates a command with the event handlers that implement the command.
The CommandBinding class contains a Command property, and PreviewExecuted, Executed, PreviewCanExecute, and CanExecute events.
Command is the command that the CommandBinding is being associated with. The event handlers which are attached to the PreviewExecuted and Executed events implement the command logic. The event handlers attached to the PreviewCanExecute and CanExecute events determine if the command can execute on the current command target.
The following example shows how to create a CommandBinding on the root Window of an application. The CommandBinding associates the Open command with Executed and CanExecute handlers.


A CommandBinding is attached to a specific object, such as the root Window of the application or a control. The object that the CommandBinding is attached to defines the scope of the binding. For example, a CommandBinding attached to an ancestor of the command target can be reached by the Executed event, but a CommandBinding attached to a descendant of the command target cannot be reached. This is a direct consequence of the way a RoutedEvent tunnels and bubbles from the object that raises the event.
In some situations the CommandBinding is attached to the command target itself, such as with the TextBox class and the Cut, Copy, and Paste commands. Quite often though, it is more convenient to attach the CommandBinding to an ancestor of the command target, such as the main Window or the Application object, especially if the same CommandBinding can be used for multiple command targets. These are design decisions you will want to consider when you are creating your commanding infrastructure.
Command Target
The command target is the element on which the command is executed. With regards to a RoutedCommand, the command target is the element at which routing of the Executed and CanExecute starts. As noted previously, in WPF the CommandTarget property on ICommandSource is only applicable when the ICommand is a RoutedCommand. If the CommandTarget is set on an ICommandSource and the corresponding command is not a RoutedCommand, the command target is ignored.
The command source can explicitly set the command target. If the command target is not defined, the element with keyboard focus will be used as the command target. One of the benefits of using the element with keyboard focus as the command target is that it allows the application developer to use the same command source to invoke a command on multiple targets without having to keep track of the command target. For example, if a MenuItem invokes the Paste command in an application that has a TextBox control and a PasswordBox control, the target can be either the TextBox or PasswordBox depending on which control has keyboard focus.


The CommandManager

The CommandManager serves a number of command related functions. It provides a set of static methods for adding and removing PreviewExecuted, Executed, PreviewCanExecute, and CanExecute event handlers to and from a specific element. It provides a means to register CommandBinding and InputBinding objects onto a specific class. The CommandManager also provides a means, through the RequerySuggested event, to notify a command when it should raise the CanExecuteChanged event.
The InvalidateRequerySuggested method forces the CommandManager to raise the RequerySuggested event. This is useful for conditions that should disable/enable a command but are not conditions that the CommandManager is aware of.






Command Library

________________________________________
WPF provides a set of predefined commands. The command library consists of the following classes: ApplicationCommands, NavigationCommands, MediaCommands, EditingCommands, and the ComponentCommands. These classes provide commands such as Cut, BrowseBack and BrowseForward, Play, Stop, and Pause.





ICommand Interface implementation
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;

namespace DelegateCommandPattern
{
///
/// DelegateCommand Class implements ICommand Interface to Create Commands for wpf application which uses MVVM Pattern.
/// Commands in WPF are created by implementing the ICommand interface.
///

public class DelegateCommand : ICommand
{
public delegate void ExecuteCommand(object parameter);
public delegate bool CanExecuteCommand(object parameter);

ExecuteCommand _execute;
CanExecuteCommand _canExecute;

public DelegateCommand(ExecuteCommand target, CanExecuteCommand canExecute)
{
_execute = target;
_canExecute = canExecute;
}

public DelegateCommand (ExecuteCommand target)
{
_execute = target;
}

#region IComamnd Implementation

///
/// CanExecuteChanged is raised if the command manager that centralizes the commanding
/// operations detects a change in the command source that might invalidate a command
/// that has been raised but not yet executed by the command binding.
///

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

///
/// This method determines whether the command can execute on the current target.
/// Normally, if the command cannot execute, the command source(like button and etc) disables itself.
///

///
///
public bool CanExecute(object parameter)
{
if (_canExecute == null)
return true;

return _canExecute.Invoke(parameter);
}

///
/// This method performs the actions that are associated with the command.
///

///
public void Execute(object parameter)
{
_execute.Invoke(parameter);
}
#endregion
}
}


No comments :

Post a Comment