需求
主菜單和一組工具欄的典型界面,則可以在菜單,工具欄,上下文菜單(例如,在主應用程序區域中單擊鼠標右鍵時)使用新建(New)或打開(Open)等操作,以及使用鍵盤快捷鍵,如Ctrl+N和Ctrl+O.
對應上面的每種行爲的響應代碼都完全一樣,但是傳統的gui 應用程序中,你不得不爲每一種行爲定義一個對應的event 然後調用相同的方法。
這不是一種理想的處理方法。
在WPF中,微軟嘗試使用命令這個概念來解決這個問題。WPF會監聽鍵盤快捷鍵,並且如果存在合適的命令,會直接調用,這使得命令成爲一個理想的在應用中提供快捷鍵的方式。
命令綁定CommandBinding
命令實際上並沒有自己做任何事情。在根目錄中,它們由ICommand接口組成,該接口僅定義一個事件和兩個方法:Execute()和CanExecute()。第一個用於執行實際操作,而第二個用於確定操作當前是否可用。
要執行命令的實際操作,您需要命令和代碼之間的鏈接,這是CommandBinding發揮作用的地方。
CommandBinding通常在Window或UserControl上定義,並保存對它處理的Command的引用,以及用於處理Command的Execute()和CanExecute()事件的實際事件處理程序。
實際用法
<Window x:Class="命令.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="100" Width="200">
<Window.CommandBindings>
<CommandBinding Command="ApplicationCommands.New" Executed="NewCommand_Executed" CanExecute="NewCommand_CanExecute" />
</Window.CommandBindings>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<Button Command="ApplicationCommands.New">New</Button>
</StackPanel>
</Window>
using System.Windows;
using System.Windows.Input;
namespace 命令
{
/// <summary>
/// MainWindow.xaml 的交互邏輯
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void NewCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
private void NewCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("The New command was invoked");
}
}
}
代碼分析:首先在window上定義了CommandBindings,並設置了3個屬性Command,Executed,CanExecute。
Command指明希望使用的命令,後兩者指定事件處理程序。
button按鈕通過屬性Command與定義的CommandBindings關聯起來。
“ApplicationCommands.New”意味着定義了一個默認的鍵盤快捷鍵Ctrl + N。所以此時按Ctrl + N和用鼠標點擊button效果一樣。
命令實際上並沒有自己做任何事情,真正做事情是綁定在Executed屬性上的NewCommand_Executed方法
<Window x:Class="命令.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="200" Width="250">
<Window.CommandBindings>
<CommandBinding Command="ApplicationCommands.Cut" CanExecute="CutCommand_CanExecute" Executed="CutCommand_Executed" />
<CommandBinding Command="ApplicationCommands.Paste" CanExecute="PasteCommand_CanExecute" Executed="PasteCommand_Executed" />
</Window.CommandBindings>
<DockPanel>
<WrapPanel DockPanel.Dock="Top" Margin="3">
<Button Command="ApplicationCommands.Cut" Width="60">_Cut</Button>
<Button Command="ApplicationCommands.Paste" Width="60" Margin="3,0">_Paste</Button>
</WrapPanel>
<TextBox AcceptsReturn="True" Name="txtEditor" />
</DockPanel>
</Window>
using System.Windows;
using System.Windows.Input;
namespace 命令
{
/// <summary>
/// MainWindow.xaml 的交互邏輯
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void CutCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = (txtEditor != null) && (txtEditor.SelectionLength > 0);
}
private void CutCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
txtEditor.Cut();
}
private void PasteCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = Clipboard.ContainsText();
}
private void PasteCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
txtEditor.Paste();
}
}
}
代碼分析:這個示例綁定了兩個命令,“ApplicationCommands.Cut"和"ApplicationCommands.Paste”,4個事件處理程序。
並關聯了兩個button。
CutCommand_CanExecute方法的返回值爲textbox不爲空,且選中的字符數大於0.
滿足條件才執行CutCommand_Executed方法。
內置命令
儘管命令實際上並沒有自己做任何事情,真正做事情是綁定在Executed屬性上的事件處理程序。
但爲了更容易,WPF團隊已定義了100多個常用命令,可以使用它們。它們分爲5類,分別稱爲ApplicationCommands,NavigationCommands,MediaCommands,EditingCommands和ComponentCommands。特別是ApplicationCommands包含很多常用操作的命令,如New,Open,Save and Cut,Copy和Paste。
內置命令的表現,就好像命令實際做了事情
以上的是示例相當於用我們自己的命令去替換了wpf的內置命令。
如果僅僅是方便快捷的使用內置命令,完全不需要自己去寫。
<Window x:Class="命令.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="200" Width="250">
<DockPanel>
<WrapPanel DockPanel.Dock="Top" Margin="3">
<Button Command="ApplicationCommands.Cut" CommandTarget="{Binding ElementName=txtEditor}" Width="60">_Cut</Button>
<Button Command="ApplicationCommands.Paste" CommandTarget="{Binding ElementName=txtEditor}" Width="60" Margin="3,0">_Paste</Button>
</WrapPanel>
<TextBox AcceptsReturn="True" Name="txtEditor" />
</DockPanel>
</Window>
using System.Windows;
using System.Windows.Input;
namespace 命令
{
/// <summary>
/// MainWindow.xaml 的交互邏輯
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
不需要CommandBindings,直接在button控件中指明
Command="ApplicationCommands.Cut" CommandTarget="{Binding ElementName=txtEditor}
就能實現文本的粘貼與複製。