了解WPF觸發程序、動作與行為

by Vivid 21. 九月 2011 01:00

.NET Magazine國際中文電子雜誌

作 者:許薰尹

審 稿:張智凱

文章編號:N110911601

出刊日期:2011/9/7

過去,若是要設計和使用者互動,通常我們會攔截事件,並撰寫事件處理程式來處理。在Expression Blend 4 開發WPF或Silverlight類型的程式時,你可以使用行為(Behavior)來達到同樣的效果。這樣的好處是,可以讓不會撰寫程式碼的美術設計人員,不用撰寫程式碼,就可以利用簡單的拖曳的方式為應用程式加上互動的能力。

動作(Action)是物件,可以被呼叫。WPF的觸發程序(Trigger)可以用來觸發一到多個動作,然後透過動作來執行一個工作,例如,按下視窗中的按鈕(Trigger),就呼叫一個方法(Action)。本文將介紹WPF中的觸發程序、動作與行為。

動作與觸發程序

我們先來探討WPF中的動作與觸發程序,以一實例說明。使用Visual Studio 2010建立一個WPF應用程式 ,然後加入一個Button到設計畫面。在<Windows>下,加入Style定義,並設定動作與觸發程序 。

     <Style x:Key="myStyle" TargetType="Button"> 
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="true">
                    <Setter Property = "Background" Value="Blue"/>
                </Trigger>
            </Style.Triggers>
        </Style>

因為使用者的動作(Action)以屬性值的型式存在,當做為觸發程序(Trigger)的IsMouseOver屬性設定為True時,就執行Background屬性設為Blue的動作(Action)。設定觸發程序時,Property與Value都要同時設定,否則便會產生例外錯誤。

在Button的XAML標籤中套用Style :

         <Button
             Style="{StaticResource myStyle}"
            x:Name="button" Content="Click" HorizontalAlignment="Left" Height="48" Margin="64,104,0,0"
            VerticalAlignment="Top" Width="80"/>

完整的程式碼看起來如下所示:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="ActionTriggerDemo.MainWindow"
    x:Name="Window"
    Title="MainWindow"
    Width="640" Height="480">
    <Window.Resources>
        <Style x:Key="myStyle" TargetType="Button">
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="true">
                    <Setter Property = "Background" Value="Blue"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <Grid x:Name="LayoutRoot">
        <Button
             Style="{StaticResource myStyle}"
            x:Name="button" Content="Click" HorizontalAlignment="Left"
            Height="48" Margin="64,104,0,0" VerticalAlignment="Top"
            Width="80"/>
    </Grid>
</Window>

此時若執行程式碼,當你將滑鼠移動到Button上方,Button的背景顏色將會變成藍色的。 被觸發程序變動的屬性值會在觸發程序的滿足條件不成立時,自動回復到先前的狀態,因此當您將滑鼠移出Button的上方時,Button的背景顏色就會變回原先的灰色,參考下圖所示。

image

使用Expression Blend 4設計觸發程序與動作

若使用Expression Blend 4設計,您可以先為Button建立一個Template,步驟是選取畫面上的Button,按滑鼠右鍵,點選「Edit Template」-> 「Edit a Copy」,參考下圖所示:

image

接下來在「Triggers」視窗中點選「+Property」按鈕,建立Property Trigger,參考下圖所示:

image

設「target-element」->「IsMouseOver」->為「true」。此時,Microsoft Expression Blend會進入巨集錄製狀態,參考下圖所示。

image

在巨集錄製中的狀態下,點選Button的「Background」屬性,然後選一個背景顏色,參考下圖所示。

image

點選紅色圓圈,結束巨集錄製,參考下圖所示。

image

執行應用程式,當滑鼠移動到Button上方,就會變顏色。

設計行為

行為(Behavior)是以WPF的觸發程序與動作為基礎而設計的,可以在不用撰寫程式碼的情況下,執行動作,以便為應用程式增加一些和使用者互動的行為。

預設當你利用Expression Blend 4 建立WPF或Silverlight類型的程式時,在「Asserts」視窗中就可以找到許多預設的觸發程序(Behavior),不同類型的專案支援不同類型的觸發程序。當然,在預設的行為不敷使用時,您可以自訂行為。常用的觸發程序包含:

  • CallMethodAction:根據觸發程序來呼叫一個方法(Method)。被呼叫的方法比需宣告為public,不可以有回傳值,也不可以有任何參數值。
  • ChangePropertyAction:根據觸發程序來變更屬性值。
  • DataStateBehavior:為一個資料行為(Data Behavior),可以用來切換Visual State。例如在文字方塊有輸入值的情況下,存檔按鈕才啟用。
  • FluidMoveBehavior:為一個有動畫效果的行為。當你移動項目到新位置時,可以有動畫效果。
  • FluidMoveSetTagBehavior:為一個有動畫效果的行為。可以將FluidMoveBehavior行為套用到List項目。
  • MouseDragElementBehavior:為一個動作行為(Motion Behavior),以便拖曳畫面中的項目。
  • TranslateZoomRotateBehavior:為一個動作行為(Motion Behavior),WPF才可以使用,Silverlight不行。用在觸控螢幕事件發生時的行為。

因為行為(Behavior)主要的目地便是讓不會寫程式的Expression Blend設計人員可以在不寫程式的前題下,讓應用程式能夠執行一些動作,我們來看看如何在Expression Blend中使用這些預設的行為。例如在Expression Blend 4 建立一個WPF應用程式,並加一個Image到畫面上,設定Source屬性,顯示一張圖。然後只要將「Asserts」->「Behaviors」->「MouseDragElementBehavior」拖曳到Image上方放開就行了,參考下圖所示。

image

XAML看起來如下:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
    x:Class="ActionTriggerDemo.Window2"
    x:Name="Window"
    Title="Window2"
    Width="640" Height="480">

    <Grid x:Name="LayoutRoot">
        <Image x:Name="pack___siteoforigin_____flower_jpg" Margin="136,48,312,0" Source="pack://siteoforigin:,,,/flower.jpg" Stretch="Fill" Height="122.475" VerticalAlignment="Top">
            <i:Interaction.Behaviors>
                <ei:MouseDragElementBehavior/>
            </i:Interaction.Behaviors>
        </Image>
    </Grid>
</Window>

在執行程式之前,你還要加入System.Windows.Interactivity.dll組件的參考,在Expression Blend的「Projects」->你的專案上方按滑鼠右鍵->「Add Reference」,然後選取 C:\Program Files\Microsoft SDKs\Expression\Blend\.NETFramework\v4.0\Libraries\System.Windows.Interactivity.dll,參考下圖所示。

image

這樣就完工了。執行程式後,你便可以拖曳圖片在視窗中到處移動,參考下圖所示。

image

自訂行為

從Expression Blend 3 版本開始,微軟提供行為的標準實作:內含在System.Windows.Interactivity組件中的System.Windows.Interactivity.Behavior<T> 類別。

System.Windows.Interactivity組件是Expression Blend的核心程式,存在於Expression Blend SDK中,而不是在.NET Framework或WPF中。因此你必需先安裝Expression Blend  SDK後才可以使用。System.Windows.Interactivity組件中包含了有Behavior<T> class,可以讓你不必安裝Expression Blend的情況下,就可以在Visual Studio 2010使用Expression Blend Behavior。

利用Expression Blend SDK可以讓你實作自己的Expression Blend Behavior。此外,Expression Blend也提供支援,能讓你新增Behavior到Element,利用「Assets」視窗來直接拖曳套用。

若要自定行為,您可以在專案中加入一個類別,命名為MyBehavior,參考下圖所示:

image

要實作Expression Blend Behavior必需要繼承Behavior<T>類別,並利用利用型別參數(type parameter) 限定Behavior可以套用的型別,例如在類別中加入以下程式碼,自訂一個MyBehavior 類別,套用到TextBox。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows.Interactivity;
using System.Windows.Media;

namespace ActionTriggerDemo {
    class MyBehavior : Behavior<TextBox> {
        protected override void OnAttached ( ) {
            this.AssociatedObject.TextChanged += new TextChangedEventHandler ( AssociatedObject_TextChanged );
        }
        void AssociatedObject_TextChanged ( object sender , TextChangedEventArgs e ) {
            string input = this.AssociatedObject.Text;
            if ( !string.IsNullOrEmpty ( input ) ) {
                this.AssociatedObject.Background = Brushes.Red;
            } else {
                this.AssociatedObject.Background = null;
            }
        }
        protected override void OnDetaching ( ) {
            this.AssociatedObject.TextChanged -= new TextChangedEventHandler ( AssociatedObject_TextChanged );
        }
    }
}

要注意,限定的型別必需繼承自DependencyObject,若無特別限制,可以直接設定為DependencyObject。Behavior類別實作了IAttachedObject介面,這個介面有兩個方法:OnAttached 與OnDetaching ,你可以改寫這兩個方法來套用或移除Behavior要執行的行為。例如範例程式中,在OnAttached 方法中註冊TextBox的TextChanged 事件,在事件發生時,判斷套用此行為的TextBox是否有輸入文字,若包含文字,則將背景顏色設定為紅色的;若不包含文字,則將背景顏色設定為預設值。

先編譯你的專案,從Expression Blend選單「Project」->「Build Project」。要套用行為到TextBox時,從「Assets」->「Locations」->選擇專案中的MyBehavior,直接拖曳到畫面上的TextBox放開,就會自動的套用到TextBox,參考下圖所示。

image

到目前為止XAML看起來如下:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
    xmlns:local="clr-namespace:ActionTriggerDemo"
    x:Class="ActionTriggerDemo.Window3"
    x:Name="Window"
    Title="Window3"
    Width="640" Height="480"
    >

    <Grid x:Name="LayoutRoot">
        <TextBox Height="23" HorizontalAlignment="Left" Margin="112,40,0,0" x:Name="textBox1" VerticalAlignment="Top" Width="120" >
            <i:Interaction.Behaviors>
                <local:MyBehavior/>
            </i:Interaction.Behaviors>
        </TextBox>
    </Grid>
</Window>

當你執行程式時,文字方塊的內容變動且不為空字串時,文字方塊的背景會自動變成紅色的。當文字方塊的內容是空白時,便回到預設的顏色,參考下圖所示。

image

總結

Expression Blend中的 行為(Behavior)是一段可重複使用的程式碼,可加到任何物件。行為可以讓你和應用程式互動,而不用寫任何程式碼。

觸發程序和動作有因果關係,觸發程序是因,動作是果。觸發程序可以呼叫一到多個動作。Action是一個物件,你可以呼叫它來執行一個動作。你可以實作一個動作來執行任何動作。
動作最好不要在呼叫之間依賴任何外部狀態,彼此之間也沒有相依關係。

下載本文範例 : code_N110911602.zip (1.26 mb)

Tags:

.NET Magazine國際中文電子雜誌 | Expression Blend | WPF | 許薰尹Vivid Hsu

新增評論




  Country flag
biuquote
  • 評論
  • 線上預覽
Loading






NET Magazine國際中文電子雜誌

NET Magazine國際中文電子版雜誌,由恆逸資訊創立於2000,自發刊日起迄今已發行超過500篇.NET相關技術文章,擁有超過40000名註冊讀者群。NET Magazine國際中文電子版雜誌希望藉於電子雜誌與NET Developer達到共同學習與技術新知分享,歡迎每一位對.NET 技術有興趣的朋友們多多支持本雜誌,讓作者群們可以有持續性的動力繼續爬文。<請加入免費訂閱>

月分類Month List