CommandBinding機制剖析及應用*****************************最近正在學習WPF,因此,有時間時會寫一些小文章,介紹Wpf中一些比較有趣和重要的東西。學習并應用技術的過程就是一個“技術拼圖”的過程,只有將各個技術碎片拼成一張完整的大圖,才算是“功德圓滿”。本文就是這張WPF技術全景拼圖中的一小塊。金旭亮2008-10-21****************" />

亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Command Binding機制剖析及應用

系統 1851 0

WPF 技術拼圖之

<?xml:namespace prefix = o />

Command Binding 機制剖析及應用

*****************************

最近正在學習WPF,因此,有時間時會寫一些小文章,介紹Wpf中一些比較有趣和重要的東西。

學習并應用技術的過程就是一個“技術拼圖”的過程,只有將各個技術碎片拼成一張完整的大圖,才算是“功德圓滿”。

本文就是這張WPF技術全景拼圖中的一小塊。


金旭亮

2008-10-21


*****************************



WPF 中,有一個非常有意思的 Command Binding (命令綁定機制),這種機制在原有的 Windows Form 中沒有提供。本文設計了一個實例,直觀地展示出 Command Binding 的應用場景,并對其機制進行了剖析。

1 Command Binding 有什么用?

這個機制有何作用?看一下下面這個例子就清楚了( 1 ),此例是由 Visual C# 2008 Express 創建的標準 Wpf 應用程序,項目中有一個 Window1.xaml 作為主窗體:


Command Binding機制剖析及應用

1

從圖中可以看到,窗體上有一個菜單和一個按鈕,當用戶點擊這兩個控件時,它們執行相同的功能。

多個控件執行同一個功能在桌面應用程序中是非常常見的,比如相同的命令可以通過選擇“菜單”命令或點擊工具欄上的特定按鈕執行。

以傳統方式開發這樣的程序,往往需要針對每個控件的 Click 事件分別編碼來實現。

然而,在許多時候我們需要同步多個控件的狀態。比如在一個文本編輯器中 ,當用戶沒有選中任何文本時,菜單中的“ Copy ”和工具欄上的“ Copy ”按鈕都需要禁用,因此,傳統方式下還必須寫額外代碼來實現這一點。

Command Binding 彌補傳統編程方式的缺陷,可以幫助我們以很少的代碼實現同樣的功能。

2 實現 Command Binding

讓我們修改示例以利用命令綁定機制。

首先,向項目中加入一個 MyAppCommands 類,其內容如下:

namespace UnderStandCommandBinding

{

public class MyAppCommands

{

public static RoutedUICommand MyCommand = new RoutedUICommand ();

}

}

請特別注意其中的 RoutedUICommand 類型的字段 MyCommand 。它定義了一個將被窗體控件所調用的命令。

Window1.cs 中書寫以下代碼:

partial class Window1 : Window

{

public Window1()

{

InitializeComponent();

CommandBinding cb = new CommandBinding();

cb.Command = MyAppCommands .MyCommand;

cb.Executed += new ExecutedRoutedEventHandler(cb_Executed);

}

void cb_Executed(object sender, ExecutedRoutedEventArgs e)

{

MessageBox.Show(" 響應自定義命令 MyCommand");

}

}

上述代碼創建一個 CommandBinding 對象,此對象指明 cb_Executed 函數響應 MyCommand 命令(其實是被 MyCommand 命令的 Execute 方法自動調用,這里借用事件處理機制的相關術語以便于理解,事實上,命令綁定與事件響應不是一回事,簡單地說,命令綁定建構于 Wpf 的事件路由機制之上)。

下一步則需要指定窗體上的哪幾個控件用于調用此命令:

partial class Window1 : Window

{

public Window1()

{

InitializeComponent();

// 創建命令對象

CommandBinding cb = new CommandBinding ();

cb.Command = MyAppCommands .MyCommand;

cb.Executed += new ExecutedRoutedEventHandler (cb_Executed);

// 將要執行的命令對象添加到窗體的命令對象集合中

this.CommandBindings.Add(cb);

// 設定菜單項和按鈕都執行 MyCommand 命令

mnuInvokeMyCommand.Command = MyAppCommands.MyCommand;

btnInvokeMyCommand.Command = MyAppCommands.MyCommand;

}

void cb_Executed(object sender, ExecutedRoutedEventArgs e)

{

MessageBox .Show( " 響應自定義命令 MyCommand" );

}

}

現在運行程序,可以發現,單擊菜單項和按鈕都會調用 cb_Executed 函數。

3 使用 XAML 實現 DataBinding

前面使用代碼實現了數據綁定。現在,改用 XAML 實現相同的功能。

首先,刪除 Window1 構造函數中的代碼,只留下 cb_Executed ()函數:

partial class Window1 : Window

{

public Window1()

{

InitializeComponent();

}

void cb_Executed(object sender, ExecutedRoutedEventArgs e)

{

MessageBox .Show( " 響應自定義命令 MyCommand" );

}

}

回到 Window1.xaml 文件中,首先,在其 Window 元素中加入對本項目命名空間的引用(其目的是在 XAML 中使用代碼中的類):

<Window x : Class ="UnderStandCommandBinding.Window1" ……

xmlns:myapp="clr-namespace:UnderStandCommandBinding" >

……

</Window

然后,修改 MenuItem 的聲明,加上 Command 屬性:

< MenuItem Header ="Invoke My Command" Name ="mnuInvokeMyCommand" Command="MyAppCommands.MyCommand" />

再修改 Button 的聲明,也加上 Command 屬性:

< Button Name ="btnInvokeMyCommand"

Command="myapp:MyAppCommands.MyCommand">

Invoke My Command

</ Button >

最后,給最頂層元素 Window 添加命令綁定:

< Window.CommandBindings >

< CommandBinding

Command="myapp:MyAppCommands.MyCommand"

Executed="cb_Executed" />

</ Window.CommandBindings >

現在運行示例,可以看到運行效果與代碼一樣。

由此可知,我們可使用 XAML 以比使用 C# 編寫代碼方式更少的代碼量實現同樣的功能。

4 實現控件同步

現在開始展示一下命令綁定的神奇之處。向窗體上加入一個 CheckBox (取名 chkActivateCommand ),我們將用它來控制是否可以執行 MyCommand 命令( 2 ):


Command Binding機制剖析及應用


2

修改命令綁定對象:

< Window.CommandBindings >

< CommandBinding Command ="myapp:MyAppCommands.MyCommand" Executed ="cb_Executed" CanExecute="CommandBinding_CanExecute" />

</ Window.CommandBindings >

Window.xaml.cs 中添加一個新函數:

private void CommandBinding_CanExecute(

object sender, CanExecuteRoutedEventArgs e)

{

e.CanExecute = chkActivateCommand.IsChecked.Value;

}

其余代碼不需要動。 OK 。現在運行一下示例程序:


Command Binding機制剖析及應用


3

可以看到,現在按鈕和菜單命令的激活與由 CheckBox 控制了。我們甚至沒有寫一行代碼去同步這三個控件的狀態!

5 向命令傳送參數

添加一個文本框 txtPara 用于輸入參數。

< TextBox Name ="txtPara" Background ="Wheat" />

控件的 CommandParameter 屬性可用來向命令對象提供參數,我們使用數據綁定機制將文本框中的文本作為命令參數:

< MenuItem Header ="Invoke My Command" Name ="mnuInvokeMyCommand" Command ="myapp:MyAppCommands.MyCommand" CommandParameter="{Binding ElementName=txtPara,Path=Text}" />

……

< Button Height ="23" Name ="btnInvokeMyCommand" HorizontalAlignment ="Center" Command ="myapp:MyAppCommands.MyCommand" CommandParameter="{Binding ElementName=txtPara,Path=Text}" > Invoke My Command </ Button >

傳入的參數會被命令響應函數的 ExecutedRoutedEventArgs 參數接收,示例程序中修改后的命令響應函數如下:

void cb_Executed( object sender, ExecutedRoutedEventArgs e)

{

MessageBox .Show( e.Parameter.ToString() );

}

運行屏幕截圖如 4


Command Binding機制剖析及應用


4

在文本框中輸入文字,點擊按鈕或菜單項,將彈出一個消息框顯示用戶輸入的文本。

我們的示例到此結束。

6 Command Binding 有何用處?

根據這個例子,大家體會到了 Command Binding 的好處了嗎?

仔細看一下 MyAppCommands 類,就發現我們可以向其中添加多個自定義的命令,只需指定好這些命令對象的 Execute CanExecute 兩個事件響應屬性,就可以方便地設定窗體上的控件執行特定的命令(通過其 Command 屬性),而且 WPF 框架會自動幫助我們同步這些控件的狀態!

這樣一來,我們就得到了一種比較模塊化的 Wpf 桌面應用程序結構:

(1) 將應用程序要執行的功能封裝到中間層組件或獨立的類中;

(2) 創建一個專用保存命令對象的類(比如本例中的 MyAppCommands 類),在此類中集中存放應用程序要執行的命令對象。

(3) 在窗體中創建命令綁定對象,為每個命令對象創建響應函數,并將其添加到 Window 對象的 CommandBindings 屬性中,之后,即可將控件與命令對象相互綁定。

這種架構的優點是增強了代碼的隔離性,并減少了總體的代碼量:

(1) 業務邏輯代碼在中間層中;

(2) 專用于提供特定命令對象的類實際上成了一個功能調用接口層,可以很方便地增刪調整程序提供的功能。

(3) 現在控件基本上不需要寫大量的代碼響應特定的事件和同步多個控件的狀態。

7 剖析 Command Binding 機制

Command Binding 機制主要與兩個接口密切相關:一個是 ICommand ,用于定義命令對象類,另一個是 ICommandSource ,用于定義可發出“調用命令”的源控件。 RoutedUICommand 類實現了 ICommand 接口,通常用此類的對象表示應用程序需要執行的命令。而 Button 等控件則實現了 ICommandSource 接口,并且擁有此接口所定義的 Command CommandParameter 屬性,可用于調用命令。

Wpf 程序主要通過以下兩種對象實現命令綁定: CommandBinding 對象將命令對象綁定到特定的命令處理函數(示例就是這樣的),當執行命令對象時,這些命令處理函數被調用(命令對象和命令響應函數的這種關系稱為“綁定”)。 InputBinding 對象將命令對象與特定的按鍵關聯起來,當用戶按下特定鍵時,相關聯的命令對象被調用。

許多 Wpf 控件都擁有 CommandBindings InputBindings 兩個集合屬性,其中成員就是 CommandBinding 對象和 InputBinding 對象,從而使這些控件能夠響應特定的命令,比如 TextBox 就是這樣,它在內部包容了響應標準的 Cut/Copy/Paste 命令對象的代碼,而 wpf 默認提供的 ApplicationCommands 類則定義了 Cut/Copy/Paste 命令對象,這就是為何我們可以不寫一行代碼直接在 TextBox 中使用 Ctl-C 等命令的緣故。

Command Binding 機制的內部機制比較復雜,簡單地說:

執行 Command 對象時,會引發 PreviewExecute/Execute PreviewCanExecute/CanExecute 事件,這些事件都是 RoutedEvent ,可以在 Wpf 元素樹中傳播(從樹葉到樹根方向稱為 Bubble ,從樹根到樹葉方向稱為 tunnel ),正是這種事件路由機制構筑了整個 Command Binding 機制運轉起來的根基。

再進一步追問一下,事件路由是如何實現的?這就涉及到 Wpf 另一個非常重要的新特性——依賴屬性。

有關路由事件和依賴屬性的剖析,將會在另外的文章中進行介紹。需要指出的是,如果您對 .NET 2.0 所提供的委托、事件等還不清楚,那么,要弄明白 wpf 的路由事件和依賴屬性比較困難。

這也再次驗證了一句老話:新路接在舊路的前頭。

好,這篇文章就寫到這里吧!

Command Binding機制剖析及應用


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 国产精品18久久久久久小说 | 狠狠色噜噜狠狠狠狠97老肥女 | se在线播放 | 午夜私人影院粉色视频我要 | 免费看一级毛片 | ww亚洲ww亚在线观看 | 亚洲国产欧美在线观看 | 99久久99这里只有免费的精品 | 午夜噜噜噜私人影院在线播放 | 国产精品大片天天看片 | 成人伊人 | 四虎成人欧美精品在永久在线 | 天天毛片| 大狠狠大臿蕉香蕉大视频 | 九九热亚洲精品综合视频 | 国产精品欧美一区二区在线看 | 欧美色xxx| 一区二区三区四区产品乱码伦 | 老司机午夜精品视频你懂的 | 四虎影视免费在线观看 | 国产美女视频做爰 | 九九热国产视频 | 欧美成人爽毛片在线视频 | 色小妹综合 | 特级一级毛片视频免费观看 | 伊人网站在线 | 一本影院| 久草在线观看视频 | 国产在线日韩 | 狠狠操狠狠操狠狠操 | 久久精品入口麻豆 | 亚洲国产精品综合久久网络 | 99热国产精品 | 亚洲成人伊人网 | 欧美性猛交xx乱大交 | 四虎在线视频观看 | 欧美国产高清 | 国产好大好爽久久久久久久 | 狠狠色噜噜狠狠狠狠五月婷 | 九九久久99 | 欧美亚洲中日韩中文字幕在线 |