https://eric0806.blogspot.tw/2013/07/wpf-custom-command.html
關鍵
<Window.CommandBindings>
<CommandBinding
Command="{StaticResource Quit}"
CanExecute="Quit_CanExecute"
Executed="Quit_Executed" />
</Window.CommandBindings>
=================================================
WPF建立自訂的Command
WPF強大的功能之一,是提供了一些系統預設Command,及可以讓使用者自訂Command的功能。
什麼是Command(命令)呢?簡單來說,我們的程式可能有好多地方要執行同一個功能,拿「複製」來講好了,可能功能表、工具列、右鍵快速功能表、快速鍵都要執行同一個功能,以前傳統視窗寫法就是在物件上點兩下,去編輯事件函數的功能,或許類似物件的事件函數參數相同,但也遇到不同型態的事件函數,這樣就無法共用,變成同樣的動作要寫好多次。
而WPF提供了Command功能,只要在程式中指定好命令名稱和該做的動作之後,任何可以使用Command功能的物件只要在XAML裡面指定Command=”命令名稱”屬性,就可以做到相同的事情了~超簡單啊!!
.net裡面預設有很多已經建立好的Command,譬如ApplicationCommands.Cut就是個「剪下」的Command(注意,這只是個名稱,並沒有實作功能,要實作必須處理Executed的事件),但有時候我們要的功能並沒有提供,像「離開程式」就沒有可對應的Command,這時我們就必須自己製作一個。
什麼是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