zoukankan      html  css  js  c++  java
  • WPF系列之二:解耦View层控件事件与ViewModel层事件的响应

    以前的做法:

    1.当项目的时间比较紧迫的时候,对UI层中控件的事件的处理,往往采取的是类似Winform中最简单的做法,直接做一个事件的Handler直接去调用VM层的方法。

    2.控件只有一个Command属性,其它的事件的处理方法没有办法和ViewModel层进行解耦的时候往往也采取上面提到的方法。

    如下图所示:

    新的做法:

    为了实现事件的处理与View层的解耦,我们可以利用WPF提供的附加属性来为需要的事件添加附加行为。附加属性扮演了一个在View层与Model层牵线的角色。

    需要下面三个步骤来实现(以Load事件为例):

    1.在ViewModel中定义一个Command属性

     winloadedCommand = new DelegateCommand(this.executeWinloadedCommand, this.canWinloadedCommand);
    实例化Command

    定义ICommand类型的command

     #region
            private ICommand winloadedCommand;
            public ICommand WinloadedCommand
            {
                get { return winloadedCommand; }
                set
                {
                    if (winloadedCommand != value)
                    {
                        winloadedCommand = value;
                        OnPropertyChagned("WinloadedCommand");
                    }
                }
            }
            private void executeWinloadedCommand()
            {
                CalculatingStatus = "The WinloadedCommand has been called!";
            }
            private bool canWinloadedCommand()
            {
                return true;
            }
            #endregion
    WinloadedCommand

    2.定义一个CommandBehaviors类,在其中定义一个ICommand类型的附加属性,并在PropertyChangedCallback的回调中链接事件与实际的command实例之间的调用。

    public static class CommandBehaviors
        {
            public static ICommand GetWindowLoadCommand(DependencyObject obj)
            {
                return (ICommand)obj.GetValue(WindowLoadCommandProperty);
            }
            public static void SetWindowLoadCommand(DependencyObject obj, ICommand value)
            {
                obj.SetValue(WindowLoadCommandProperty, value);
            }
            // Using a DependencyProperty as the backing store for WindowLoadCommand.  This enables animation, styling, binding, etc...
            public static readonly DependencyProperty WindowLoadCommandProperty =
                DependencyProperty.RegisterAttached("WindowLoadCommand", typeof(ICommand), typeof(CommandBehaviors), new PropertyMetadata(null, OnWindowLoadedCommandPropertyChanged));
            public static void OnWindowLoadedCommandPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                var frameworkElement = d as FrameworkElement;
                if (frameworkElement != null && e.NewValue is ICommand)
                {
                    frameworkElement.Loaded
                      += (obj, args) =>
                         {
                             if ((e.NewValue as ICommand).CanExecute(obj))
                             {
                                 (e.NewValue as ICommand).Execute(null);
                             }
                         };
                }
            }
        }
    CommandBehaviors

    3.在xaml中进行Binding

    大功告成,运行示例如下:

    思考1:如何实现带有参数的调用?Event-〉Command

    1.如果参数数据来源于控件本身的属性,可以在链接Event与Command时直接传递参数

    2.如果数据来自外界,可以在CommandBehaviors类中定义额外的附加属性,然后将参数绑定到此属性上面,当调用command时,检查该属性。

    完毕。

    作者:Andy Zeng

    欢迎任何形式的转载,但请务必注明出处。

    http://www.cnblogs.com/andyzeng/p/3708276.html 

  • 相关阅读:
    校园网络(tarjan)
    消息扩散(强连通分量)
    上帝造题的七分钟(树桩数组乱搞)
    数颜色 / 维护队列(带修莫队)
    Luogu5155 [USACO18DEC]Balance Beam
    分数规划小结
    Luogu3177 [HAOI2015]树上染色
    Luogu4402 机械排序
    Luogu3201 [HNOI2009]梦幻布丁
    Luogu3380 二逼平衡树
  • 原文地址:https://www.cnblogs.com/andyzeng/p/3708276.html
Copyright © 2011-2022 走看看