Silverlight中的Action與Trigger


最近做的Silverlight項目上用到了大量的拖拽,自動跟隨等功能,由於趕時間,加上對Silverlight半生不熟,用的是最簡單也是最不好維護的方法。項目忙完了閑下來,想重構一下代碼,想起了Trigger和Action這兩個東西,當初接觸這兩個東西不深,只是認識,不知道用。現在正好可以好好學習一下,參考了重多大神的代碼之后,終於初步熟悉了它們。這里分享一下我對Trigger和Action的認識。

我用一個最簡單的例子來說明Action與Trigger,點擊一個Button彈出MessageBox。

建立一個Silverlight Application,引用System.Windows.Interactivity.dll程序集(這個程序集很重要,是使用Trigger,Action,Behavior必須引用的)。我們在MainPage里放一個Button並給一個Click事件。

xaml代碼如下:

   1: <UserControl x:Class="SilverlightApplication1.MainPage"
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   5:     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   6:     mc:Ignorable="d"
   7:     d:DesignHeight="300" d:DesignWidth="400">
   8:  
   9:     <Grid x:Name="LayoutRoot" Background="White">
  10:         <Button Content="Button" HorizontalAlignment="Left" Margin="35,31,0,0" Name="button1" VerticalAlignment="Top" Click="button1_Click" />
  11:     </Grid>
  12: </UserControl>

cs代碼如下:

   1: public partial class MainPage : UserControl
   2: {
   3:     public MainPage()
   4:     {
   5:         InitializeComponent();
   6:     }
   7:  
   8:     private void button1_Click(object sender, RoutedEventArgs e)
   9:     {
  10:         MessageBox.Show("Hello World!");
  11:     }
  12: }

很簡單,這是最傳統的做法。

下面Action要上場了。所謂Action,就是去執行某些操作。可以根據需要創建自己的Action,常見的需要創建Action的情況有:改變屬性、調用方法、打開窗口、導航到某個頁面、設置焦點等。自定義Action可從 TriggerAction<DependencyObject>或TargetedTriggerAction<DependencyObject>繼承,區別在於操作對象是關聯對象還是特定的目標對象,實現時覆蓋Invoke方法即可。我們新建一個簡單的Action,代碼如下:

   1: public class Action1 : TriggerAction<DependencyObject>
   2: {
   3:     public Action1()
   4:     {
   5:         
   6:     }
   7:  
   8:     protected override void Invoke(object o)
   9:     {
  10:         MessageBox.Show("Hello World! This message comes from an action.");
  11:     }
  12: }

在Invoke方法里Show一個MessageBox。這樣,一個Action這創建好了。如何使用它呢?看下面的代碼。

xaml代碼:

   1: <UserControl x:Class="SilverlightApplication1.MainPage"
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   5:     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   6:     xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
   7:     xmlns:local="clr-namespace:SilverlightApplication1"
   8:     mc:Ignorable="d"
   9:     d:DesignHeight="300" d:DesignWidth="400">
  10:  
  11:     <Grid x:Name="LayoutRoot" Background="White">
  12:         <Button Content="Button" HorizontalAlignment="Left" Margin="35,31,0,0" Name="button1" VerticalAlignment="Top">
  13:             <i:Interaction.Triggers>
  14:                 <i:EventTrigger EventName="Click">
  15:                     <local:Action1 />
  16:                 </i:EventTrigger>
  17:             </i:Interaction.Triggers>
  18:         </Button>
  19:     </Grid>
  20: </UserControl>

運行結果如圖:

image

很顯然,Button的單擊調用了那個Action,Button不再去觸發xaml.cs里的那個事件處理方法了,而了觸發了之前新建的Action1。回到xaml代碼,EventTrigger是Silverlight自帶的一個觸發器(Trigger)。Trigger一量觸發,就會執行對應的Action。這里我們把Action1與EventTrigger關聯到一起(“關聯”這個詞可能用得不合適,反正就這個意思),EventTrigger觸發Click事件,執行Action彈出MessageBox。而xaml.cs文件里的代碼不再需要了。它的好處是不是已經看出來了?有效的分離了UI與后台代碼。

下面Trigger正式登場。所謂Trigger,就是監聽某些條件的變化,比如事件觸發,屬性值改變等,進而觸發一些動作的發生。這些Triggers可能是EventTrigger、CollisionTrigger 等,當然更多的或許是創建自己的Trigger。自定義Trigger只需要從TriggerBase<DependencyObject>繼承,並覆蓋OnAttached和OnDetaching方法即可。我面來創建一個Trigger。代碼如下:

   1: public class Trigger1 : TriggerBase<Button>
   2: {
   3:     protected override void OnAttached()
   4:     {
   5:         base.OnAttached();
   6:         this.AssociatedObject.Click += new RoutedEventHandler(Trigger1_Click);
   7:     }
   8:  
   9:     protected override void OnDetaching()
  10:     {
  11:         base.OnDetaching();
  12:         this.AssociatedObject.Click -= new RoutedEventHandler(Trigger1_Click);
  13:     }
  14:  
  15:     protected void Trigger1_Click(object sender, RoutedEventArgs e)
  16:     {
  17:         MessageBox.Show("Hello World! This message comes from a trigger.");
  18:     }
  19: }

代碼中我們用到了AssociationObject這個屬性,這個屬性表示綁定Trigger的對象,這里是一個Button,OnAttached中注冊一個Click事件處理方法,OnDetching中取消注冊(如果不取消注冊,當這個Button上其它觸發器觸發時,這個觸發器的效果還會重現,因為Click觸發之后委托鏈上所有注冊方法都會執行, 具體情況具體分析是否需要取消注冊)。

在Xaml中這樣來使用這個Trigger:

   1: <Grid x:Name="LayoutRoot" Background="White">
   2:     <Button Content="Button" HorizontalAlignment="Left" Margin="35,31,0,0" Name="button1" VerticalAlignment="Top">
   3:         <i:Interaction.Triggers>
   4:             <local:Trigger1 />
   5:         </i:Interaction.Triggers>
   6:     </Button>
   7: </Grid>

運行如果如下:

image

這里Trigger1被觸發了。

其實,觸發器(Trigger)和動作(Action)是協同工作的。當某事件發生的時候,Trigger就會觸發並調用一個Action,Trigger和Action組成了最簡單的行為(Behavior下次再討論)表現形式。

最后,我們讓Trigger1和Action1協同工作一下。Trigger1的代碼改一改:

   1: public class Trigger1 : TriggerBase<Button>
   2: {
   3:     protected override void OnAttached()
   4:     {
   5:         base.OnAttached();
   6:         this.AssociatedObject.Click += new RoutedEventHandler(Trigger1_Click);
   7:     }
   8:  
   9:     protected override void OnDetaching()
  10:     {
  11:         base.OnDetaching();
  12:         this.AssociatedObject.Click -= new RoutedEventHandler(Trigger1_Click);
  13:     }
  14:  
  15:     protected void Trigger1_Click(object sender, RoutedEventArgs e)
  16:     {
  17:         InvokeActions(null);
  18:     }
  19: }

Trigger1_Click方法里調用InvokeActions來執行“關聯”到這個Trigger上的Action。Xaml如下:

   1: <Grid x:Name="LayoutRoot" Background="White">
   2:     <Button Content="Button" HorizontalAlignment="Left" Margin="35,31,0,0" Name="button1" VerticalAlignment="Top">
   3:         <i:Interaction.Triggers>
   4:             <local:Trigger1>
   5:                 <local:Action1 />
   6:             </local:Trigger1>
   7:         </i:Interaction.Triggers>
   8:     </Button>
   9: </Grid>

運行結果如下:

image

這里,Button綁定了Trigger1,Attach這個Trigger1時把Click事件注冊上(OnAttached方法。關於Attach,請參考“附加屬性”),所以單擊Button就調用了綁定在Trigger1上的Action1。

至於這兩個東西的好處就不必多說了,分離了UI與代碼,提高了代碼的復用。

好了,初學Trigger和Action,大致縷了一下它們之間的關系,就簡單介紹到這,歡迎一起討論。更神奇的Behavior將在下篇中介紹大笑

 

附上上面的源代碼


免責聲明!

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



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