• 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类库的一些影子.这种模式可能在以后框架的发展中用的越来越多.

    好了,这篇就介绍到这里,希望大家对附加行为有一个基本的认识.

  • 相关阅读:
    最新28个很棒的 jQuery 教程
    NetBeans 为PHP添加调试功能
    HTML5 存储API介绍
    PHP 变量判断
    jquery 与其它js 框架的解决办法
    从按下电源开关到bash提示符
    tar、gzip、unzip命令的详细使用方法
    Top命令中Load Average的含义
    Linux(BASH)命令搜索机制
    分析df和du的区别
  • 原文地址:https://www.cnblogs.com/Clingingboy/p/prism_part4.html
Copyright © 2020-2023  润新知