WPF基礎之命令


 理解命令

    傳統的設計在需要地方添加事件處理程序,並使用各個事件處理程序調用恰當的應用程序方法。如下圖,許多應用程序任務可通過各種不同的路由觸發,所以經常編寫多個事件處理程序來調用相同的應用程序方法。本身這並不是什么問題。但當需要處理用戶界面狀態時,問題就變復雜了。如果要禁用PrintDocumnt()任務。需要禁用兩個菜單命令和一個工具欄按鈕,使它們不能被單擊並且禁用Ctrl+P快捷鍵。編寫代碼完成這些工作很麻煩。
 
WPF使用新的命令模型解決這個問題。它增加了兩個重要特性。
  • 將事件委托到適當的命令。
  • 使控件的啟用狀態和相應命令的狀態保持同步。

 WPF命令模型

WPF命令模型具有如下4個重要元素
  • 命令:命令表示應用程序任務,並且跟蹤任務是否能被執行。然而,命令實際上不包含執行應用程序任務的代碼。
  • 命令綁定:每個命令綁定針對用戶界面的具體區域,將命令連接到相關的應用程序邏輯,這種分解的設計是非常重要的,因為每個命令可用於應用程序的多個地方, 並且每個地方具有不同的意義。為處理這一問題,需要同一命令與不同的命令綁定。
  • 命令源:命令源觸發命令.例如:MenuItem和Button都是命令源。單擊他們會執行綁定命令。
  • 命令目標:命令目標是在其中執行命令的元素。例如,Paste命令可在TextBox控件中插入文本,而OpenFile命令可在DocumentViewer中打開文檔。

 ICommand接口

      WPF命令模型的核心是System.Windows.Input.ICommand接口。
 public interface ICommand
    {
        void Execute(object parameter);
        bool CanExecute(object parameter);
        event EventHandler CanExecuteChanged;
    }
  • Execute()方法將包含應用程序任務邏輯。
  • CanExecute()方法返回命令的狀態。
  • 通過CanExecuteChanged事件,當命令可用時,命令源可自動啟用自身,當命令不可用時,禁用自身。

 RoutedCommand類

     RoutedCommand類是WPF中唯一實現了ICommand接口的類。所有WPF命令都是RoutedCommand類及其派生類的實例。

 RoutedUICommand類

     RoutedUICommand類繼承自RoutedCommand類,WPF提供的所有預先構建好的命令都是RoutedUICommand對象。

 命令庫

WPF提供了基本命令庫,基本命令庫中保存的命令超過100條,這些命令通過以下5個專門的靜態類的靜態屬性控制。
  • ApplicationCommands:該類提供了通用命令。包括剪切板命令(如Copy、Cut、Paste)以及文檔命令(如New、Open、Save、Save As和Print)
  • NavigationCommands:該類提供了用於導航的命令,包括基於頁面的應用程序設計的一些命令,如BrowseBack、BrowseForward和NextPage。
  • EditingCommands:該類提供了許多重要的文檔編輯命令。包含用於移動的命令,MoveToLineEnd、MoveLeftByWord和MoveUpByPage,選擇內容命令SelectToLineEnd、SelectLeftByWord。
  • ComponentCommands:改類提供了由用戶界面組件使用的命令,包括用於移動和選擇內容的命令,這些命令和EditingCommand類中的一些命令類似。
  • MediaCommands:該類提供了一組用於處理多媒體的命令,如Play、Pause、NextTrack以及IncreaseVolume。

 命令源

命令庫中的命令始終可用。觸發他們最簡單的方法是將他們關聯到實現了ICommandSource接口的控件,其中包括繼承自ButtonBase類的控件,Button和CheckBox、ListBoxItem、HypeLink以及MenuItem。
ICommandSource接口定義了三個屬性
  • Command 指向連接的指令。
  • CommandParameter 提供其他希望隨命令發送的數據。
  • CommandTarget確定將在其中執行命令的元素。
使用Command屬性連接到ApplicationCommands.New
 <Button Command="ApplicationCommands.New">New</Button>

 命令綁定

      當命令關聯到命令源時,命令源將會被自動禁用。如上按鈕,查詢了命令的狀態,而且由於命令還沒有與其關聯的綁定,所以按鈕是禁用的。

 代碼創建綁定

CommandBinding binding = new CommandBinding(ApplicationCommands.New);
binding.Executed+=binding_Executed;
this.CommandBindings.Add(binding);
xaml
 <Window.CommandBindings>
        <CommandBinding Command="ApplicationCommands.New" Executed="binding_Executed"></CommandBinding>
 </Window.CommandBindings>
 <StackPanel>
        <Button Command="ApplicationCommands.New">New</Button>
 </StackPanel>

 

 使用多命令源

 <Menu>
        <MenuItem Header="File">
            <MenuItem Command="New"></MenuItem>
        </MenuItem>
    </Menu>

 微調命令文本

      菜單可以自動提取命令項文本。button 要實現此功能。
 <Button Command="New" Content="{Binding RelativeSource={RelativeSource Self},Path=Command.Text}"></Button>

 直接調用命令

  ApplicationCommands.New.Execute(null, targetElement);
  this.CommandBindings[0].Command.Execute(null);

 

 禁用命令

     需求文本變時,保存按鈕才可用
  public GridDemoWindow()
        {
            InitializeComponent();
            CommandBinding binding = new CommandBinding(ApplicationCommands.Save);
            binding.Executed+=binding_Executed;
            binding.CanExecute+=binding_CanExecute;
            this.CommandBindings.Add(binding);
        }
        private void binding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = isDirty;
        }
        private void binding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            throw new NotImplementedException();
        }
        private void txt_TextChanged(object sender,RoutedEventArgs e)
        {
            isDirty = true;
        }

 

 自定義命令

 
public class DataCommands
    {
        private static RoutedUICommand requery;
        static DataCommands()
        {
            InputGestureCollection inputs = new InputGestureCollection();
            inputs.Add(new KeyGesture(Key.R, ModifierKeys.Control, "Ctrl+R"));
            requery = new RoutedUICommand("Requery","Requery",typeof(DataCommands),inputs);
        }
        public static RoutedUICommand Requery
        {
            get { return requery; }
        }
    }

 

引用命名空間
xmlns:local="clr-namespace:Commands"

 

使用命令
<Window.CommandBindings>
        <CommandBinding Command="local:DataCommands.Requery" Executed="binding_Executed"></CommandBinding>
    </Window.CommandBindings>
    <StackPanel>
        <Button Command="local:DataCommands.Requery">Requery</Button>
    </StackPanel>         
                                                                                                                                                                                        


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM