命令(Command) 2018/1/10 19:06:35 命令可以約束代碼,還可以約束步驟邏輯。(事件的作用是發佈和傳播一些消息,對如何響應事件不做規定,每個接收者可以使用自己的行為來響應事件。也就是說事件不具有約束力) 命令系統的基本元素 ·命令(Command):實際上就是實現了IComma ...
命令(Command)
2018/1/10 19:06:35
命令可以約束代碼,還可以約束步驟邏輯。(事件的作用是發佈和傳播一些消息,對如何響應事件不做規定,每個接收者可以使用自己的行為來響應事件。也就是說事件不具有約束力)
命令系統的基本元素
·命令(Command):實際上就是實現了ICommand介面的類,平時使用最多的是RoutedCommand類
·命令源(Command Source):實現了ICommandResource介面的類(Button)
·命令目標(Command Target):必須是實現了IInputCommand介面的類
·命令關聯(Command Binding):負責把外圍邏輯與命令關聯起來,比如執行之前對命令是否可以執行進行判斷、命令執行後還有哪些後續工作等
命令的使用
1.創建命令類
即獲得一個實現ICommand介面的類,如果命令與具體業務邏輯無關,則使用WPF類庫中的RoutedCommand即可。如果想得到與業務邏輯相關的專有命令,則需要創建RoutedCommand(或者ICommand)的派生類。
2.聲明命令實例
技巧:一般情況下,只需要操作一個命令實例與之對應即可。因此程式中的命令多使用單件模式(Singletone Pattern)以減少代碼複雜度。
3.指定命令源
命令源擁有命令和命令源兩個屬性。
同一個命令可以有多個源。
一旦把命令指派給命令源,命令源就會受命令影響,命令不能執行的時候作為命令源的控制項不可用。革命臨官發送命令的方式不盡相同,例如單機雙擊。
4.指定命令目標
命令目標不是命令的屬性而是命令源的屬性。無論這個命令源是否擁有焦點都會收到這個命令。如果沒有指定命令目標,預設為當前焦點對象就是命令目標。
5.設置命令關聯(命令綁定)
WPf需要CommandBinding在執行前幫助判斷是不是可以執行,在執行後做一些事件來“打掃戰場”。命令目標向命令關聯發送路由事件,命令關聯捕捉並處理路由事件,向命令反饋信息。
類
1.ICommand介面包含兩個方法和一個事件
Execute()方法包含應用程式邏輯(例如列印文檔);
CanExecute()方法返回命令狀態(命令可用返回true,不可用返回false);
CanExecuteChanged事件,命令狀態改變時引發,這是指示信號,表示應當調用CanExecute()檢查命令狀態。
2.RoutedCommand類自動實現ICommmand介面的類
不包含任何應用程式邏輯,只代表命令。為事件冒泡和隧道添加了一些額外的基礎結構
3.RoutedUICommand類繼承自RoutedCommand類
用於具有文本的命令,只增加了Text屬性
執行命令
RoutedUIIcommand類沒有任何編碼的功能,只表示命令。為觸發命令,需要有命令源(也可使用代碼)。為響應命令,需要有命令綁定,命令綁定將執行轉發給普通的事件處理程式。
1.命令源
ICommandSource定義了三個屬性:
·Command:指向連接的命令,必需
·CommandParameter:提供其他希望隨命令發送的數據
·CommandTarget:確定將在其中執行命令的元素
例如:下麵的按鈕使用Command屬性連接到ApplicationCommands.New命令:
<Button Command="ApplicationCommands.New">New</Button>
2.命令綁定
明確:
·當命令被觸發時執行什麼操作
·如何確定命令是否能被執行(可選)
·命令在何處起作用
命令實例:
定義一個命令,使用Button來發送這個命令,當命令送達TextBox時,TextBox被清空(如果沒有文字則不發送命令)
·界面代碼:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Command"
Background="LightBlue" Height="350" Width="525">
<StackPanel x:Name="stackPanel">
<Button x:Name="button1" Content="Send Command" Margin="5"/>
<TextBox x:Name="textBoxA" Margin="5,0" Height="100"/>
</StackPanel>
</Window>
·後臺代碼:
//實現:定義一個命令,使用Button來發送這個命令,當命令送達TextBox時,TextBox被清空(如果沒有文字則不發送命令)
namespace WpfApplication1
{
/// <summary>
/// MainWindow.xaml 的交互邏輯
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
InitializeCommand();
}
//聲明並定義命令
private RoutedCommand clearCmd = new RoutedCommand("CLear", typeof(MainWindow));
private void InitializeCommand()
{
//把命令賦值給命令源(發送者)並指定快捷鍵
this.button1.Command = this.clearCmd;
this.clearCmd.InputGestures.Add(new KeyGesture(Key.C, ModifierKeys.Alt));//按Alt+C鍵
//指定命令目標
this.button1.CommandTarget = this.textBoxA;
//創建命令關聯
CommandBinding cb = new CommandBinding();
cb.Command = this.clearCmd;//只關註與clearCmd相關的事件
cb.CanExecute += new CanExecuteRoutedEventHandler(cb_CanExecute);
cb.Executed +=new ExecutedRoutedEventHandler(cb_Executed);
//把命令關聯安置在外圍控制項上
this.stackPanel.CommandBindings.Add(cb);
}
//當探測命令是否可以執行時,此方法被調用
void cb_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
if(string.IsNullOrEmpty(this.textBoxA.Text))
{ e.CanExecute = false; }
else
{ e.CanExecute = true; }
//避免繼續向上傳而降低程式性能
e.Handled = true;
}
//當命令送達目標後,此方法被調用
void cb_Executed(object sender, ExecutedRoutedEventArgs e)
{
this.textBoxA.Clear();
//避免繼續向上傳而降低程式性能
e.Handled = true;
}
}
解釋:
·運行程式,在TextBox中輸入文字後Button在命令可執行狀態的情況下變為可用,此時單擊Button或者按Alt+C鍵,TextBox都會被清空。
·RoutedCommand並不對命令目標做任何操作,而是由CommandBinding操作的。
·無論是探測命令是否執行還是命令送達目標,都會激發命令目標發送路由事件,這些路由事件會沿著UI元素樹向上傳遞並最終被CommandBinding所捕捉。
·CommandBinding被安裝在外圍的StackPanel上,CommandBinding起一個偵聽器的作用,而且專門針對clearCmd命令捕捉與其相關的路由事件。
·當CommandBinding捕捉到CanExecute事件,就會調用cb_CanExecute方法判斷命令執行條件是否滿足,並反饋給命令供其影響命令源的狀態;當捕捉到Execute事件,表示命令的Execute方法已經執行了,或者說命令已經作用在了命令目標上(RoutedCommand只負責讓命令目標激發Executed),則調用Executed方法。
·CommandBingding一定要設置在命令目標的外圍控制項上,不然無法捕捉到CanExecute和Executed等路由事件。
命令庫
命令具有“一處聲明,處處使用”的特點。便攜的命令庫包括:ApplicationCommands,ComponentCommands,NavigationCommands,MediaCommands,EditingCommands.都是靜態類。例如我們可以直接拿命令庫用這些標準命令,不需要自己聲明:Open,Save,Play,Stop。(屬於ApplicationCommand)
自定義Command
---------------------待更新