WPF命令模型由許多可變的部分組成。總之,它們都具備以下4個重要元素:工具
1、ICommand接口spa
WPF命令模型的核心是System.Windows.Input.ICommand接口,該接口定義了命令的工做原理。該接口包含兩個方法和一個事件:設計
public interface ICommand { void Execute(object parameter); bool CanExecute(object parameter); event EventHandler CanExecuteChanged; }
在一個簡單實現中,Execute()方法將包含應用程序任務邏輯(例如,打印文檔)。然而,正以下一節中將看到,WPF的實現更復雜。它使用Execute()方法引起一個更復雜的過程,該過程最終觸發在應用程序其餘地方處理的事件。經過這種方式可使用預先準備好的命令類,並插入本身的邏輯。還能夠靈活地再幾個不一樣地方使用同一個命令(如Print命令)。code
CanExecute()方法返回命令的狀態——若是命令可用,就返回true;若是不可用,就返回false。Execute()和CanExecute()方法都接受一個附加的參數對象,可以使用該對象傳遞所需的任何附加信息。對象
最初,當命令狀態改變時引起CanExecuteChanged事件。對於使用命令的任何事件,這是指示信號,表示它們應當調用CanExecute()方法檢查命令的狀態。經過使用該事件,當命令可用時,命令源(如Button或MenuItem)可自動啓用自身;當命令不可用時,禁用自身。blog
2、RoutedCommand類繼承
當建立本身的命令時,不會直接實現ICommand接口;而是使用System.Windows.Input.RoutedCommand類,該類自動實現了ICommand接口。RoutedCommand類是WPF中惟一實現了ICommand接口的類。換句話說,全部WPF命令都是RoutedCommand類及其派生類的實例。接口
在WPF命令模型背後的一個重要概念是,RoutedCommand類不包含任何應用程序邏輯,而只表明命令,這意味着各個RoutedCommand對象具備相同的功能。事件
RoutedCommand類爲事件冒泡和隧道添加了一些額外的基礎結構。鑑於ICommand接口封裝了命令的思想——可被觸發的動做並可被啓用或禁用——RoutedCommand類對命令進行了修改,使命令可在WPF元素層次結構中冒泡,以便得到正確的事件處理程序。路由
爲支持路由事件,RoutedCommand類私有地實現了ICommand接口,並添加了ICommand接口方法的一些不一樣版本。最明顯的變化是,Execute()和CanExecute()方法使用了一個額外參數。下面的新的簽名:
public void Execute(object parameter,IInputElement target) { //... } public void CanExecute(object parameter,IInputElement target) { //... }
參數target是開始處理事件的元素。事件從target元素開始,而後冒泡至高層的容器,直到應用程序爲了執行合適的任務而處理了事件(爲了處理Executed事件,元素還須要藉助於另外一個類——CommandBinding類的幫助)。
除上面的修改外,RoutedCommand類還引入了三個屬性:命令名稱(Name屬性)、包含命令的類(OwnerType)以及任何可用於觸發命令的按鍵或鼠標操做(位於InputGestures集合中)。
3、RoutedUICommand類
在程序中處理的大部分命令不是RoutedCommand對象,而是RoutedUICommand類的實例,RoutedUICommand類繼承自RoutedCommand類(實際上,WPF提供的全部預先構建好的命令都是RoutedUICommand對象)。
RoutedUICommand類用於具備文本的命令,這些文本顯示在用戶界面中的某些地方(例如菜單項文本、工具欄按鈕的工具欄提示)。RoutedUICommand類只添加了Text屬性,該屬性是爲命令顯示的文本。
爲命令定義命令文本(而不是直接在控件上定義文本)的優勢是可在某個位置執行本地化。但若是命令文本永遠不會在用戶界面的任何地方顯示,那麼RoutedUICommand類和RoutedCommand類是等效的。
4、命令庫
WPF設計者認識到,每一個應用程序可能都有大量命令,而且對於許多不一樣的應用程序,不少命令時通用的,例如,全部基於文檔的應用程序都有他們本身版本的New、Open以及Save命令。爲減小建立這些命令所需的工做,WPF提供了基本命令庫,基本命令庫中保存的命令超過100條。這些命令經過如下5個專門的靜態類的屬性提供:
ApplicationCommands類提供了一組基本命令,在全部類別的應用程序中都常常會用到這些命令,因此在此簡單介紹一下。下面列出了全部這些命令。
New | Copy | SelectAll |
Open | Cut | Stop |
Save | Paste | ContextMenu |
SaveAs |
Delete | CorrectionList |
Close | Undo | Properties |
Redo | Help | |
PrintPreview | Find | |
CancelPrint | Replace |
例如,ApplicationCommands.Open是提供RoutedUICommand對象的靜態屬性,該對象表示應用程序中的Open命令。由於ApplicationCommands.Open是靜態屬性,因此在整個應用程序中只有一個Open命令實例。然而,根據命令源的不一樣(換句話說,是在用戶界面的什麼地方觸發的該命令),可採用不一樣的處理方式。
每一個命令的RoutedUICommand.Text屬性和名稱是相互匹配的,指示在單詞之間添加了空格。例如,ApplicationCommands.SelectedAll命令的文本時SelecteAll(Name屬性使用相同的沒有空格的文本)。由於Open命令時ApplicationCommands類的靜態屬性,因此RoutedUICommand.OwnerType屬性返回ApplicationCommands類的類型對象。
這些單獨的命令對象僅時一些標誌起,不具備實際功能。然而,許多命令對象都有一個額外的特徵:默認輸入綁定。例如,ApplicationCommands.Open命令被映射到Ctrl+O快捷鍵。只要將命令綁定到命令源,併爲窗口添加命令源,這個快捷鍵就會被激活,即便沒有在用戶界面的任何地方顯示該命令也一樣如此。