1. 程式人生 > >Prism V2之旅(4)

Prism V2之旅(4)

     上篇介紹了RegionAdapter的作用及如何如何擴充套件RegionAdapter的方法.

這篇向大家介紹一個在wpf中非常實用的功能Attach Behavior.我們稱之為附加行為.

附加行為在Web領域的流行

 

如果你知道asp.net ajax框架就一定會知道AJAX Control Toolkit.雖然裡面的很多功能華而不實,但這種實現方式確實非常值得學習.你可以再次開啟其展示的網站回顧一下其用法,如下面程式碼的方式

 <asp:TextBox ID="TextBox1" runat="server" />
 <sample:FocusBehavior runat="server"
ID="FocusBehavior1" 
HighlightCssClass="MyHighLight"
NoHighlightCssClass="MyLowLight"
TargetControlID="TextBox1" />

 

 

在這裡發幾句牢騷,ajaxControlToolKit一個簡單的功能,需要依賴於多個基類,光談設計沒問題, 但必須考慮到,我們是在做web,儘量不要載入不必要的指令碼檔案,在你使用其提供的日曆擴充套件時,你就會發展其指令碼無比大.而且功能不易擴充套件.我曾經看過一些商業控制元件,也是基於asp.net ajax的.因為面向物件的設計,一個控制元件的指令碼能載入到300k左右.這不知道該怪控制元件開發者還是框架設計者呢?我想還是因為web的特性關係,讓我們放不開手腳在javascript上做面向物件,做到適用即可.

如果你用過jQuery的話,那麼它的小巧和易擴充套件性你是絕對可以感受到的,你是否有曾經一段時間在網上瘋狂的找jQuery外掛的經歷呢?

jQuery外掛其實就等同於asp.net ajax的行為擴充套件(Behavior),兩個框架的擴充套件行為數量並不是一個數量級的.所以jQuery對於大多數人來講是非常好的選擇.

附加行為在wpf的使用

 

行為是一個元件,它擴充套件與其關聯的 DOM 元素的功能。這是asp.net ajax框架的行為的一種解釋.

那麼套用在wpf上,則是行為是一個元件,它擴充套件與其關聯的元素(也可稱控制元件)的功能

附加行為是一種模式,與附加屬性不同,但它的實現方式可以藉助附加屬性的方式.如下示例

<fxui:TextBox x:Name="searchTextBox" Margin="2" Grid.Column="1">
  <fxui:Interaction.Behaviors>
    <fxui:AutoCommit ButtonName="searchButton" />
  </fxui:Interaction.Behaviors>
</fxui:TextBox>

這個擴充套件是nikhilk在silverlight使用附加行為的模式做了一個擴充套件.你可以參考他寫的關於Behavior的文章,同時也可以參考另外一篇文章.

nikhilk(牛人啊…)擴充套件的silverlight類庫很有參考價值,大家可以下載作為學習.

Interaction.Behaviors是一個包含附加行為結合的附加屬性,AutoCommit 是一個擴充套件的附加行為

讓我們來看一下Behavior的基礎設計,Behavior定義了兩個方法,OnAttach方法就是擴充套件關聯元素的功能,OnDetach則取消相關聯元素的擴充套件功能.當Behavior新增到BehaviorCollection集合內時則觸發OnAttach方法,移除的時候則觸發OnDetach方法.這便是附加行為的基本使用方法了。

image

 

附加行為在prism框架中的使用

 

在Bootstrapper載入程式中,prism預設註冊了一些附加行為,其是通過一個名為IRegionBehaviorFactory的簡單的工廠類實現的.預設附加行為如下,你也可以通過重寫Bootstrapper的ConfigureDefaultRegionBehaviors方法擴充套件prism框架的預設附加行為.

protected virtual IRegionBehaviorFactory ConfigureDefaultRegionBehaviors()
{
    var defaultRegionBehaviorTypesDictionary = Container.TryResolve<IRegionBehaviorFactory>();

    if (defaultRegionBehaviorTypesDictionary != null)
    {
        defaultRegionBehaviorTypesDictionary.AddIfMissing(AutoPopulateRegionBehavior.BehaviorKey, 
            typeof(AutoPopulateRegionBehavior));

        defaultRegionBehaviorTypesDictionary.AddIfMissing(BindRegionContextToDependencyObjectBehavior.BehaviorKey,
            typeof(BindRegionContextToDependencyObjectBehavior));

        defaultRegionBehaviorTypesDictionary.AddIfMissing(RegionActiveAwareBehavior.BehaviorKey,
            typeof(RegionActiveAwareBehavior));

        defaultRegionBehaviorTypesDictionary.AddIfMissing(SyncRegionContextWithHostBehavior.BehaviorKey,
            typeof(SyncRegionContextWithHostBehavior));

        defaultRegionBehaviorTypesDictionary.AddIfMissing(RegionManagerRegistrationBehavior.BehaviorKey,
            typeof(RegionManagerRegistrationBehavior));

    }
    return defaultRegionBehaviorTypesDictionary;

}

 

在上篇介紹RegionAdapter的時候,我們還有一些問題沒有回答,現在可以來消除這些疑問了

IRegion有一個Behaviors集合,我們再來看一遍RegionAdapter其中的Initialize方法

public IRegion Initialize(T regionTarget, string regionName)
{
    if (regionName == null)
        throw new ArgumentNullException("regionName");

    IRegion region = CreateRegion();
    region.Name = regionName;

    SetObservableRegionOnHostingControl(region, regionTarget);

    Adapt(region, regionTarget);
    AttachBehaviors(region, regionTarget);
    AttachDefaultBehaviors(region, regionTarget);
    return region;
}

 

AttachDefaultBehaviors方法會把prism框架預設註冊的附加行為,新增到IRegion的行為集合裡面,同時你也可以通過重寫AttachBehaviors方法,擴充套件IRegion的功能.以下是AttachDefaultBehaviors方法的實現

protected virtual void AttachDefaultBehaviors(IRegion region, T regionTarget)
{
    IRegionBehaviorFactory behaviorFactory = this.RegionBehaviorFactory;
    if (behaviorFactory != null)
    {
        DependencyObject dependencyObjectRegionTarget = regionTarget as DependencyObject;

        foreach (string behaviorKey in behaviorFactory)
        {
            if (!region.Behaviors.ContainsKey(behaviorKey))
            {
                IRegionBehavior behavior = behaviorFactory.CreateFromKey(behaviorKey);

                if (dependencyObjectRegionTarget != null)
                {
                    IHostAwareRegionBehavior hostAwareRegionBehavior = behavior as IHostAwareRegionBehavior;
                    if (hostAwareRegionBehavior != null)
                    {
                        hostAwareRegionBehavior.HostControl = dependencyObjectRegionTarget;
                    }
                }

                region.Behaviors.Add(behaviorKey, behavior);
            }
        }
    }

}

 

也就是說IRegion的功能由全域性的附加行為和自定義的附加行為組成的.這個附加行為的特性就給IRegion的擴充套件留下了很大的空間.我們要了解IRegion還提供了什麼功能,可以先了解下預設註冊的這些附加行為.

關於prism框架提供的這些預設的附加行為,可以參考prism框架設計者的一篇文章.其實在prism框架可以看到nikhilk擴充套件的那個silverlight類庫的一些影子.這種模式可能在以後框架的發展中用的越來越多.

好了,這篇就介紹到這裡,希望大家對附加行為有一個基本的認識.