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

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

  • 相关阅读:
    Docker容器启动时初始化Mysql数据库
    使用Buildpacks高效构建Docker镜像
    Mybatis 强大的结果集映射器resultMap
    Java 集合排序策略接口 Comparator
    Spring MVC 函数式编程进阶
    换一种方式编写 Spring MVC 接口
    【asp.net core 系列】6 实战之 一个项目的完整结构
    【asp.net core 系列】5 布局页和静态资源
    【asp.net core 系列】4. 更高更强的路由
    【Java Spring Cloud 实战之路】- 使用Nacos和网关中心的创建
  • 原文地址:https://www.cnblogs.com/Clingingboy/p/prism_part4.html
Copyright © 2011-2022 走看看