【WPF學習】第三十一章 WPF命令模型

  WPF命令模型由許多可變的部分組成。總之,它們都具備以下4個重要元素:工具

  •   命令:命令表示應用程序任務,而且跟蹤任務是否可以被執行。然而,命令實際上不包含執行應用程序任務的代碼。
  •   命令綁定:每一個命令綁定針對用戶界面的具體區域,將命令鏈接到相關的應用程序邏輯。這種分解的設計是很是重要的,由於單個命令可用於應用程序中的多個地方,而且在每一個地方具備不一樣的意義。爲處理這一問題,須要將同一命令與不一樣的命令綁定。
  •   命令源:命令源觸發命令。例如,MenuItem和Button都是命令源。單擊它們都會執行綁定命令。
  •   命令目標:命令目標是在其中執行命令的元素。例如,Paste命令可在TextBox控件中插入文本,而OpenFile命令可在DocumentViewer中打開文檔。根據命令的本質,目標可能很重要,也可能不重要。

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:該類提供了通用命令,包括剪貼板命令(如Copy、Cut和Paste)以及文檔命令(如New、Open、Save、SaveAs和Print等)。
  •   NavigationCommands:該類提供了用於導航的命令,包括爲基於頁面的應用程序設計的一些命令(如BrowseBack、BrowSeForward和NextPage),以及其餘適合於基於文檔的應用程序的命令(如IncreaseZoom和Refresh).
  •   EditingCommands:該類提供了許多重要的文檔編輯命令,包括用於移動的命令(MoveToLineEnd、MoveLeftByWord和MoveUpByPage等),選擇內容的命令(SelectToLineEnd、SelectLeftByWord),以及改變格式的命令(ToggleBold和ToggleUnderLine)。
  •   ComponentCommands:該類提供了由用戶界面組件使用的命令,包括用於移動和選擇內容的命令,這些命令和EditingCommands類中的一些命令相似(甚至徹底相同)。
  •   MediaCommands:該類提供了一組用於處理多媒體的命令(如Play、Pause、NextTrack以及IncreaseVolume).

  ApplicationCommands類提供了一組基本命令,在全部類別的應用程序中都常常會用到這些命令,因此在此簡單介紹一下。下面列出了全部這些命令。

New Copy SelectAll
Open Cut Stop
Save Paste ContextMenu

SaveAs

Delete CorrectionList
Close Undo Properties
Print 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快捷鍵。只要將命令綁定到命令源,併爲窗口添加命令源,這個快捷鍵就會被激活,即便沒有在用戶界面的任何地方顯示該命令也一樣如此。

相關文章
相關標籤/搜索