1. 基本知识
微软预定义了5类100多个常用命令:
ApplicationCommands, NavigationCommands, MediaCommands, EditingCommands and ComponentCommands.
命令的好处:
1).一处定义,到处使用(menu item, toolbar, shortcut)
2).自动监听快捷键
3).根据条件自动更新UI(enable/disable)
命令绑定:
Commands本身什么也不做,它底层由ICommand组成,包含两个方法(Execute/CanExecute)一个事件(CanExecuteChanged).要执行实际的action,需要将command和你的代码关联起来,这就是Command bindings.
可以像事件一样理解command,有人触发command,有人处理command:
1)Command binding决定用哪个command要被触发;
2)框架负责触发(执行)command;
3)command具体做什么,由我们的代码决定.
The RoutedCommand in WPF is similar to RoutedEvents. The caller raises (executes) the command and the command routes up in the WPF Visual Tree until a CommandBinding handles the command. You can stop the route by setting the = true in the command handler.
command由4部分組成:
命令: 表示应用程序的任务,并且跟踪任务是否能执行(命令实际上不包含执行应用程序任务的代码)
命令綁定:UI和命令的关联
命令源:触发命令的对象,比如菜单,按钮
命令目標:在其中执行命令的元素,比如paste命令在TextBox中执行,TextBox就是命令目标
2. xaml中创建命令绑定
<!-- xaml中创建命令绑定:
1)添加想要的命令的命令绑定到窗口的命令绑定集合 -->
<>
<CommandBinding Command=""
Executed="OpenCommand_Executed"
CanExecute="OpenCommand_CanExecute"/>
</>
<!-- xaml中创建命令绑定:
2)UI通过Command属性关联到命令 -->
<Button Content="Open" Command="" Margin="10" ="1"/>
<!-- xaml中创建命令绑定:
3)后台代码处理OpenCommand_Executed/OpenCommand_CanExecute两个事件 -->
private void OpenCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
("Open command triggered by " + ());
}
private void OpenCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
= false;
}
3.后台创建命令绑定
public MainWindow()
{
InitializeComponent();
//后台代码创建命令绑定
CreateNewCommandBinding();
}
private void CreateNewCommandBinding()
{
//后台代码创建命令绑定:1)添加绑定到窗口
//创建绑定
CommandBinding binding = new CommandBinding();
//添加事件处理
+= NewCommand_Executed;
+= NewCommand_CanExecute;
//注册
this.(binding);
}
//后台代码创建命令绑定:2)实现两个事件NewCommand_Executed/NewCommand_CanExecute
private void NewCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
("New command triggered by " + ());
}
private void NewCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
= true;
}
<!-- 后台代码创建命令绑定:
3) xaml中,UI通过Command属性关联到命令 -->
<!--
<Button Content="New" Command="" Margin="10"/>
-->
<Button ToolTip="{Binding RelativeSource={RelativeSource Self}, Path=}"
Command="" Margin="10">
<Image Source="" Height="16"/>
</Button>
4.使用微软预定义好的命令
//1)xaml
<>
<CommandBinding Command=""
CanExecute="CutCommand_CanExecute"
Executed="CutCommand_Executed" />
<CommandBinding Command=""
CanExecute="PasteCommand_CanExecute"
Executed="PasteCommand_Executed" />
</>
<DockPanel>
<WrapPanel ="Top" Margin="3">
<Button Command="" Width="60">_Cut</Button>
<Button Command="" Width="60" Margin="3,0">_Paste</Button>
</WrapPanel>
<TextBox AcceptsReturn="True" Name="txtEditor" />
</DockPanel>
//2)code-behind
//下面两个,一个是判断命令是否可以执行,另一个是实际要执行的代码
//实际上微软为预定义的command提供了默认的处理,
//所以如果想用默认处理,那么下面的代码都可以省掉不用写。
private void CutCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
= (txtEditor != null) && ( > 0);
}
private void CutCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
();
}
//下面两个,一个是判断命令是否可以执行,另一个是实际要执行的代码
private void PasteCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
= ();
}
private void PasteCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
();
}
5.自定义RoutedUICommand
//1)定义一个静态类,用于放置我们自定义的所有命令
public static class CustomCommands
{
public static readonly RoutedUICommand Exit = new RoutedUICommand
(
"Exit",//text
"Exit",//name
typeof(CustomCommands),//owner type
new InputGestureCollection()//gesture collection
{
new KeyGesture(Key.F4, )
}
);
//Define more commands here, just like the one above
}
//2)准备命令实际要执行的代码,
private void ExitCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
= true;
}
private void ExitCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
();
}
<!-- 3)命令注册到窗口, -->
<>
<CommandBinding Command="local:"
CanExecute="ExitCommand_CanExecute"
Executed="ExitCommand_Executed" />
</>
<!-- 4)命令绑定到UI -->
<Grid x:Name="myGrid">
<!-- 菜单绑定到自定义的Exit命令 -->
<Menu>
<MenuItem Header="File">
<MenuItem Command="local:" />
</MenuItem>
</Menu>
<StackPanel ="1" HorizontalAlignment="Center" VerticalAlignment="Center">
<!-- 按钮也绑定到自定义的Exit命令 -->
<Button Command="local:" Width="160" Margin="0, 10, 0, 10">Exit</Button>
</StackPanel>
</Grid>
6.自定义ICommand
WPF所有命令都从ICommand派送实现,该接口有两个方法和一个事件:
public interface ICommand
{
event EventHandler CanExecuteChanged;
bool CanExecute(object parameter);
void Execute(object parameter);
}
我们也可以从ICommand派生实现自己的Command。
//1)派生实现自定义command
public class CommandChangeColor : ICommand
{
#region ICommandInterface
public bool CanExecute(object parameter)
{//CommandParameter="{Binding ElementName=MainWnd}"
var control = parameter as Control;
if (null == control)
return false;
return true;
}
public void Execute(object parameter)
{
var control = parameter as Control;
var random = new Random();
byte r = (byte)(255);
byte g = (byte)(255);
byte b = (byte)(255);
SolidColorBrush brush = new SolidColorBrush((255, r, g, b));
= brush;
}
// Notice here: the events should be passed to the command manager to take care about it
///2008/06/17/allowing-commandmanager-to-query-your-icommand-objects/
public event EventHandler CanExecuteChanged
{
add { += value; }
remove { -= value; }
}
#endregion
}
//2)UI绑定命令
<!-- 按钮绑定到自定义的CommandChangeColor命令, 并且传了参数 -->
<Button Command="{StaticResource CommandChangeColor}"
CommandParameter="{Binding ElementName=MainWnd}"
Width="160" Margin="0, 10, 0, 10" Content="ChangeColor"/>