silverlight   发布时间:2022-05-04  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了MVVM设计模式之旅 – 通用的命令附加行为大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

概述

标题:Adventures in MVVM – Generalized Command Behavior Attachments    网上有很多关于WPF和Silverlight技术描述附加行为的例子。在WVVM模型中这些例子对命令绑定结合的非常好。不过有个问题是,对每一个行为,都会有许伴随代码,因为依赖属性必须是静态的,他们不能被抽象成普通的类。    如果你想附加为一个Control控件添加

标题Adventures in MVVM – Generalized Command Behavior Attachments

   网上有很多关于WPF和Silverlight技术描述附加行为的例子。在WVVM模型中这些例子对命令绑定结合的非常好。不过有个问题是,对每一个行为,都会有许伴随代码,因为依赖属性必须是静态的,他们不能被抽象成普通的类。

   如果你想附加为一个Control控件添加@L_739_2@mouseEnterBehavior的行为,你需要创建两到三个依赖属性在MouseEnter这个类中。他们分别是MouseEnter.Command,MouseEnter.MouseEnterBehavior 和可供选择的MouseEnter.CommandParameter.

 public class MouseEnter 
    {
        private static readonly DependencyProperty BehaviorProperty =
            DependencyProperty.RegisterAttached(
                "MouseEnterBehavior",typeof(MouseEnterBehavior),typeof(Control),null);

        public static readonly DependencyProperty CommandProperty =
            DependencyProperty.RegisterAttached(
                "Command",typeof(ICommand),typeof(MouseEnter),new PropertyMetadata(OnSetCommand));

        public static readonly DependencyProperty CommandParameterProperty =
            DependencyProperty.RegisterAttached(
                "CommandParameter",typeof(object),new PropertyMetadata(OnSetParameter))
//接下来就是处理一些依赖属性的更改

        private static void OnSetCommand(DependencyObject dependencyObject,DependencyPropertyChangedEventArgs args)
        {
            var target = dependencyObject as Control;
            if (target == null)
                return;

            GetOrCreateBehavior(target).Command = args.NewValue as ICommand;
        }

        private static void OnSetParameter(DependencyObject dependencyObject,DependencyPropertyChangedEventArgs args)
        {
            var target = dependencyObject as Control;
            if (target != null)
            {
                GetOrCreateBehavior(target).CommandParameter = args.NewValue;
            }
        }

        protected static MouseEnterBehavior getOrCreateBehavior(Control control)
        {
            var behavior = control.GetValue(BehaviorProperty) as MouseEnterBehavior;
            if (behavior == null)
            {
                behavior = new MouseEnterBehavior(control);
                control.SETVALue(BehaviorProperty,behavior);
            }

            return behavior;
        }

     然依赖属性是静态的,但是Silverlight 仍然需要你添加静态的Get和Set方法

        public static void SetCommand(Control control,ICommand command) { control.SETVALue(CommandProperty,command); }
        public static ICommand GetCommand(Control control) { return control.GetValue(CommandProperty) as ICommand; }
        public static void SetCommandParameter(Control control,object parameter) { control.SETVALue(CommandParameterProperty,parameter); }
        public static object GetCommandParameter(Control buttonBasE) { return buttonBase.GetValue(CommandParameterProperty); }

    经典的案例就是复制粘贴,完成其他相同的功能。为题就是你需要更改三处不同的类型和许多字符串。
如果你调用的不得当,那么将不会程序讲不会起作用。能编译,但是就是不能运行,或者程序停在在xaml中出现转化错误

每当我必须运用复制粘贴达到重用时,我便很沮丧,畏缩。在这种情况下,那些是绝对必须要的,如this。
我相信降低风险的方法就是粘贴之后疯狂的而复杂的更改。这就是之所以提出用AttachmentBasse这个类来达到通用的代码的原因。

上述代码就可以缩减为:

 public class MouseEnter : Attachment<Control,MouseEnterBehavior,MouseEnter>
    {
        private static readonly DependencyProperty BehaviorProperty = Behavior();
        public static readonly DependencyProperty CommandProperty = Command(BehaviorProperty);
        public static readonly DependencyProperty CommandParameterProperty = Parameter(BehaviorProperty);

        public static void SetCommand(Control control,parameter); }
        public static object GetCommandParameter(Control buttonBasE) { return buttonBase.GetValue(CommandParameterProperty); }
    }

这里你如果需要复制,你仅仅需要修改第一行就行了。

1.类名是什么?MouseEnter,修改两处

2.行为应该附加到那中类型的控件上?Control

3.你想附加那种类型的行为?MouseEnterBehavoir

 处理减少配置复杂程度外,实际代码有原来的58行,缩短到11行代码,我认为这是一个伟大的胜利。

      这这块代码中,我用到了来自prism框架中的CommandBehaviorBase类,他是通用约束中的一部分。如果你想对你的Behaviors用一些其他东西,替代他,按照你想的。我确信你自己的关于命令行为的基类将是非常的简洁。

下面就是Attachment的基类:

 

 public class Attachment<TargetT,BehaviorT,AttachmentT>
        where TargetT : Control
        where BehaviorT : CommandBehaviorBase<TargetT>
    {
        public static DependencyProperty Behavior()
        {
            return DependencyProperty.RegisterAttached(
                typeof(BehaviorT).Name,typeof(BehaviorT),typeof(TargetT),null);
        }

        public static DependencyProperty Command(DependencyProperty behaviorProperty)
        {
            return DependencyProperty.RegisterAttached(
                "Command",typeof (ICommand),typeof(AttachmentT),new PropertyMetadata((target,args) => OnSetCommandCallBACk(target,args,behaviorProperty)));
        }

        public static DependencyProperty Parameter(DependencyProperty behaviorProperty)
        {
            return DependencyProperty.RegisterAttached(
                "CommandParameter",typeof (object),typeof (AttachmentT),args) => OnSetParameterCallBACk(target,behaviorProperty)));
        }

        protected static void OnSetCommandCallBACk(DependencyObject dependencyObject,DependencyPropertyChangedEventArgs e,DependencyProperty behaviorProperty)
        {
            var target = dependencyObject as TargetT;
            if (target == null)
                return;

            GetOrCreateBehavior(target,behaviorProperty).Command = e.NewValue as ICommand;
        }

        protected static void OnSetParameterCallBACk(DependencyObject dependencyObject,DependencyProperty behaviorProperty)
        {
            var target = dependencyObject as TargetT;
            if (target != null)
            {
                GetOrCreateBehavior(target,behaviorProperty).CommandParameter = e.NewValue;
            }
        }

        protected static BehaviorT GetOrCreateBehavior(Control control,DependencyProperty behaviorProperty)
        {
            var behavior = control.GetValue(behaviorProperty) as BehaviorT;
            if (behavior == null)
            {
                behavior = Activator.CreateInstance(typeof(BehaviorT),control) as BehaviorT;
                control.SETVALue(behaviorProperty,behavior);
            }

            return behavior;
        }
    }

最后,为了完成例子,这里给出MouseEnterBehavoior 的示例:

 public class MouseEnterBehavior : CommandBehaviorBase<Control>
    {
        public MouseEnterBehavior(Control SELEctabLeobject)
            : base(SELEctabLeobject)
        {
            SELEctabLeobject.MouseEnter += (sender,args) => ExecuteCommand();
        }
    }


  在Xaml中应用该行为,如下:

<Button Behaviors:MouseEnter.Command="{Binding MouseEnter}" Behaviors:MouseEnter.CommandParameter="Optional Paremeter"/> 


                 *********************翻译文章结束*********************

第一次翻译,不足之处还请大家多多包涵。之后继续退出WPF相关翻译的文章,请关注……

原文地址:http://geekswithblogs.net/HouseOfBilz/archive/2009/08/21/adventures-in-mvvm-ndash-generalized-command-behavior-attachments.aspx

 本文章转载请声明文章出处,以表示对作者的尊重。谢谢。

大佬总结

以上是大佬教程为你收集整理的MVVM设计模式之旅 – 通用的命令附加行为全部内容,希望文章能够帮你解决MVVM设计模式之旅 – 通用的命令附加行为所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。