Event&Command 之二—— Configuring Command
Configuring Command
l You can associate any number of UI controls or input gestures with a command and bind that command to a handler that is executed when controls are activated or gestures are performed. Commands also keep track of whether they are available. If a command is disabled, UI elements associated with that command are disabled, too.
l 命令构架包含4个主要元素:
1. 命令对象(Command object)表明任务;
2. 也有命令源(command source);一个命令源是一个控制或者输入,能在被使用时,触发其关联命令;
3. 当命令被发起,命令句柄(command handler)是一个方法,
4. CommandBinding是一个对象,来track command、source和handler.
Four principal parts of the command architecture: Command object; command source; command handler; CommandBinding.
Five static classes in the Command Library: ApplicationCommands, ComponentCommands, EditingCommands, MediaCommands, and NavigationCommands.
.1. A High-Level Procedure for Implementing a Command
1. Decide on the command to use, whether it is one of the static commands exposed by the .NET Framework or a custom command.
2. Associate the command with any controls in the user interface and add any desired input gestures to the command.
3. Create a method to handle the command.
4. Create a CommandBinding control that binds the Command object to the command handler and, optionally, to a method that handles Command.CanExecute.
5. Add the command binding to the Commands collection of the control or Window control where the command is invoked.
.1.1. Invoking Commands 发起命令
Invoke it by associating it with a control, using a gesture, or invoking it directly from code.
.1.1.1. Associating Commands with Controls
很多界面元素实施了ICommandSource接口,在XAML标签中,增加command属性,就能在click时,自动激活这个command.
<Button Command="ApplicationCommands.Find" Height="23" HorizontalAlignment="Right" Margin="0,0,38,80" Name="Button3" VerticalAlignment="Bottom" Width="75">Button</Button>
.1.1.2. Invoking Commands with Gestures
可以使用Command对象来注册鼠标和keyboard gesture,当gesture发生时激活命令。
ApplicationCommands.Find.InputGestures.Add(new MouseGesture(MouseAction.LeftClick, ModifierKeys.Control)); // find命令和ctrl+鼠标右击事件绑定
ApplicationCommands.Find.InputGestures.Add(new
KeyGesture(Key.Q, ModifierKeys.Control));// find命令和Ctrl+Q绑定
.1.1.3. Invoking Commands from Code
在有些控制事件中没有暴露command属性,则只能直接从代码中invoke command,代码为:Command.Excute
ApplicationCommands.Find.Execute(aParameter, TargetControl);
//aParameter指特定对象,这个对象包含了command需要的参数,如果command不需要参数,则使用NULL值。
//TrgetControl指当命令发起时的控制,在运行时会开始冒泡的去找CommandBindings,直到找到位置。
.1.2. Command Handlers and Command Bindings
发起一个 Command,不做任何事情,没有任何动作的,必须和command Handler和Command Bindings一起去做事情。
.1.2.1. Command Handlers
Any method with the correct signature can be a command handler(command句柄是一个对象,方法也是一个对象,所以有的时候这两个东西可以相等的,说了一通废话!)
private void myCommandHandler(object sender, ExecutedRoutedEventArgs e)
{// Handle the command here}
// ExecutedRoutedEventArgs是从 RoutedEventArgs中派生,有RoutedEventArgs的所有成员。
//以上方法,暴露了command属性,则返回一个已经处理完毕的command对象。
.1.3. Command Bindings
CommandBinding对象是将所有的命令结构组合在一起。CommandBinding对象把命令和命令句柄关联在一起。
l C#的命令绑定
CommandBinding abinding = new CommandBinding();
//new一个CommandBinding对象:abinding
abinding.Command = ApplicationCommands.Find;
//将Commandbinding对象和Command对象关联起来
abinding.Executed += new ExecutedRoutedEventHandler(myCommandHandler);
this.CommandBindings.Add(abinding);
//指定command handler
l XAML的命令绑定
<Window.CommandBindings>
<CommandBinding Command="ApplicationCommands.Find" Executed="myCommandHandler" />
</Window.CommandBindings>
.1.4. Command Bubbling 冒泡寻找命令
Command和routed events一样,在视图树当中是冒泡发起的。因此通过设置ExecutedRoutedEventArgs.Handled = true可以取消冒泡发起.
默认值为false.
private void myCommandHandler(object sender, ExecutedRoutedEventArgs e)
{
// Handle the command here
e.Handled = true;
}
.1.5. Disabling Commands
任何一个命令没有进行命令绑定的,这个命令都会自动失效,即:当命令发起时,没有任何动作,并且任何命令都会出现disabled。
但是可能有这种需求,主动Disable命令。例如实现在文档被选中时,才出现打印命令。这个就需要任命一个方法来处理RoutedCommand.CanExecute事件。
1.create a method to handle the CanExecute event。确保应用的状态能Execute;
bool canExecute; // 如果 canExecute=false,则这个方法不能被执行
void abinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = canExecute;
}
2. Set the CanExecute handler on CommandBinding to point to this method:
// Assumes that you have already created a CommandBinding called abinding
abinding.CanExecute += new CanExecuteRoutedEventHandler(abinding_CanExecute);
3. Alternatively create the binding in XAML,
<Window.CommandBindings>
<CommandBinding Command="ApplicationCommands.Find" Executed="CommandBinding_Executed"
CanExecute="abinding_CanExecute" />
</Window.CommandBindings>
.1.6. Creating Custom Commands
l 最好使用静态类去实现定制化命令的静态类
l Best practice is to follow the .NET framework pattern and create static classes that expose static instances of the custom command, e.g:
public class MyCommands
{
private static RoutedUICommand launch_command; //静态参数
static MyCommands() //静态构造
{
InputGestureCollection myInputGestures = new
InputGestureCollection(); //在静态构造中NEW一个输入定制集合
myInputGestures.Add(new KeyGesture(Key.L, ModifierKeys.Control)); //加入一个 key gesture
launch_command = new RoutedUICommand("Launch", "Launch",
typeof(MyCommands), myInputGestures);
}
// 初始化一个RoutedUICommand实例,对外暴露一个Launch的命令,返回一个只读的lanch_command值;
public RoutedUICommand Launch{
get
{
return launch_command;
}
}
}
.1.7. Using the Custom Command in XAML:
l create the custom command as described above;
l add a namespace mapping to your Window XAML:
l 这个例子中Custom Command在一个单独的namespace中,叫WpfApplication13.CustomCommands
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:CustomCommands="clr-namespace:WpfApplication13.CustomCommands"
Title="Window1" Height="300" Width="300">
<!—The rest of the XAML is omitted-->
</Window>
l use the mapped XAML namespace in your XAML code, e.g:
<Button Command="CustomCommands:MyCommands.Launch" Height="23"
HorizontalAlignment="Left" Margin="60,91,0,0" Name="Button1"
VerticalAlignment="Top" Width="75">Button</Button>
浙公网安备 33010602011771号