什麼是Command(命令)呢?簡單來說,我們的程式可能有好多地方要執行同一個功能,拿「複製」來講好了,可能功能表、工具列、右鍵快速功能表、快速鍵都要執行同一個功能,以前傳統視窗寫法就是在物件上點兩下,去編輯事件函數的功能,或許類似物件的事件函數參數相同,但也遇到不同型態的事件函數,這樣就無法共用,變成同樣的動作要寫好多次。
而WPF提供了Command功能,只要在程式中指定好命令名稱和該做的動作之後,任何可以使用Command功能的物件只要在XAML裡面指定Command=”命令名稱”屬性,就可以做到相同的事情了~超簡單啊!!
.net裡面預設有很多已經建立好的Command,譬如ApplicationCommands.Cut就是個「剪下」的Command(注意,這只是個名稱,並沒有實作功能,要實作必須處理Executed的事件),但有時候我們要的功能並沒有提供,像「離開程式」就沒有可對應的Command,這時我們就必須自己製作一個。
目標:按下Ctrl+W快速鍵就能夠關閉程式
方法一:
- 在XAML中,<Window.Resources>區段中建立一個RoutedUICommand
<Window.Resources> <RoutedUICommand x:Key="Quit" Text="離開程式" /> </Window.Resources>
這樣就建立了一個名為”Quit”的自訂Command定義。 - 再來我們要建立快速鍵的指定,在<Window.InputBindings>裡面加入:
<Window.InputBindings> <KeyBinding Gesture="Ctrl+W" Command="{StaticResource Quit}" /> </Window.InputBindings>
這樣我們就將Quit的Command與快速鍵Ctrl+W連結在一起了,在任何地方按這個快速鍵就會去執行Quit。 - 但現在還沒有任何可執行的功能,所以我們要來指定一下Quit這個Command的實際處理程序。Command總共分CanExecute和Executed這兩個事件,CanExecute回傳是否可執行這個命令,我們可在面做些判斷;而Executed這個事件就是實際去執行該有的動作啦。首先我們先在原始CS檔裡面撰寫好這兩個命令的函數:
/// <summary> /// Quit命令的實際執行動作 /// </summary> /// <param name="sender"></param> /// <param name="args"></param> void Quit_Executed(object sender, ExecutedRoutedEventArgs args) { this.Close(); } /// <summary> /// 判斷是否能執行Quit命令 /// </summary> /// <param name="sender"></param> /// <param name="args"></param> void Quit_CanExecute(object sender, CanExecuteRoutedEventArgs args) { args.CanExecute = true; //這裡永遠回傳true,表示永遠都可執行,可自己加入譬如正在跑什麼動作的話就回傳false }
- 接著我們就來綁定這兩個事件,在<Window.CommandBindings>裡面新增一個CommandBinding:
<Window.CommandBindings> <CommandBinding Command="{StaticResource Quit}" CanExecute="Quit_CanExecute" Executed="Quit_Executed" /> </Window.CommandBindings>
- 做到此,我們的程式已經有了快速鍵Ctrl+W離開程式的功能啦~若希望其他物件點下去也能有這功能,只要加入屬性Command=”{StaticResource Quit}”就可以囉~
方法二:
如果你覺得寫Class比較帥,而且可以自己定義命名空間方便管理的話,也可以完全透過程式來達成。
- 新增一個Class,也順便指定一下Namespace(這裡假設我的專案叫MyProject)
using System.Windows.Input; namespace MyProject.MyCommands { class SystemCommands { /// <summary> /// 關閉應用程式的自訂Command /// </summary> public static RoutedUICommand Quit = new RoutedUICommand("離開應用程式", "QuitCommand", typeof(MainWindow)); } }
- 一樣如方法一的步驟三,先新增兩個事件的處理函數。
- 在主XAML的程式碼檔的建構子裡面,增加CommandBinding物件:
CommandBinding cbQuit = new CommandBinding( MyProject.MyCommands.SystemCommands.Quit, new ExecutedRoutedEventHandler(Quit_Executed), new CanExecuteRoutedEventHandler(Quit_CanExecute) ); //加到CommandBindings裡面 this.CommandBindings.Add(cbQuit);
- 再增加InputBinding物件:
InputBinding ibQuit = new InputBinding( MyProject.MyCommands.SystemCommands.Quit, new KeyGesture(Key.W, ModifierKeys.Control) //就是Ctrl+W ); //加到InputBindings裡面 this.InputBindings.Add(ibQuit);
- 整個段完成如下:
public MainWindow() { InitializeComponent(); CommandBinding cbQuit = new CommandBinding( MyProject.MyCommands.SystemCommands.Quit, new ExecutedRoutedEventHandler(Quit_Executed), new CanExecuteRoutedEventHandler(Quit_CanExecute) ); this.CommandBindings.Add(cbQuit); InputBinding ibQuit = new InputBinding( MyProject.MyCommands.SystemCommands.Quit, new KeyGesture(Key.W, ModifierKeys.Control) ); this.InputBindings.Add(ibQuit); }
- 回到XAML裡,在頂部元素<Window>裡面原有的xmlns底下加上自訂的命名空間:
xmlns:My="clr-namespace:MyProject.MyCommands"
- 這樣有物件要使用該命令的話,只需增加底下屬性即可:
Command="My:SystemCommands.Quit"
這樣就大功告成啦~當然你要把兩個方法結合也是可以的,我的作法就是寫自訂Command的Class,在XAML裡面指定CommandBinds和InputBinds,然後加入自訂的命名空間,這樣設計和程式撰寫對我來說是比較直觀的。
參考資料:
http://msdn.microsoft.com/zh-tw/magazine/cc785480.aspx
http://www.cnblogs.com/gnielee/archive/2010/07/16/wpf-custom-hotkey-command.html
參考資料:
http://msdn.microsoft.com/zh-tw/magazine/cc785480.aspx
http://www.cnblogs.com/gnielee/archive/2010/07/16/wpf-custom-hotkey-command.html
沒有留言:
張貼留言