• MVVM RelayCommand 进阶技巧 CanExcute 的使用


    Command模式是设计模式中一个很重要也是十分好用的一个模式。

    具体见Wiki : http://en.wikipedia.org/wiki/Command_pattern

       

    SilverLight中定义了一个ICommand接口,该接口即为Command pattern的一个实现,接口定义如下:

       

       

    可以由上图看出CanExecute方法中用来定义命令是否可被执行的逻辑。

    这个接口和我们的项目密切相关,因为RelayCommand就是ICommand接口的一个具体实现。

       

    目前在我们的项目中很多ViewModel中使用了RelayCommand 并通过binding的方式将UI的操作Binding到Command上面,

    但多数ViewModel只是通过Command来封装操作,而忽略了ICommand接口提供的另一个方法:CanExecute

       

    RelayCommand其实并非我们使用的那么简单,它内部有着另外一个被忽略的功能。

       

    让我们看一下目前RenrenUI中定义的RelayCommand中的部分代码:

    我们可以清楚的看到RelayCommand类就是ICommand接口的一个具体实现,而在Execute方法被调用的时候,会首先执行CanExecute方法。

       

       

    我们再看一下RelayCommand的参数定义:

    可以看到第二个参数为即为 Relaycommand内部 canExecute方法。

       

       

    这将对我们ViewModel中Command的实现产生深远的影响。(目前执行函数中首先检查网络是否可用的函数随处可见)

       

    让我们看一个具体的应用场景:

       

    PoiDetailViewModel 在这个页面中取得详细信息的函数为如下声明:

       

    这种写法在其他页面也十分常见,但此处存在一个问题,就是将CanExecute逻辑和Execute逻辑混淆在一起了,逻辑混淆意味着可维护性的降低,比如增加逻辑条件等。

    同时也会导致存在大量判断是否可执行的重复代码。

       

       

    我们应用前面说到的CanExecute对此进行重构:

       

    在调用这个方法的时候,之前的方式为:

    _poiDetailViewModel.GetPoiBaseInfoByPid();
    封装成Command之后相应的改为:

    _poiDetailViewModel.GetPoiBaseInfoByPidCommand.Execute(null);

    但这种在页面后台代码中直接调用Command不推荐,应该用Binding方式实现。

       

    修改完代码后,我们在CanXXX方法内加入断点可以看到,调用时CanXXX方法确实被执行:

       

       

    总结:

    虽然看上去写CanExecute方法需要增加一个方法的定义,但是如此实现更加灵活,比如检测网络和检测用户是否登录的操作可封装在一个CanExecute

    方法里面。大大增加了开发和维护成本,并且使代码更加简洁,逻辑更加清晰。

       

    MVVM架构不意味着简单的将原来后台代码挪到ViewModel中,对于这个UI架构我们应做更深的了解。

       

    关于RelayCommand的使用介绍到这里,具体有疑问和不同看法欢迎与我沟通。

       

       

       

       

       

       

       

       

  • 相关阅读:
    .NET 4.5 is an in-place replacement for .NET 4.0
    python Argparse模块的使用
    linux的fork(), vfork()区别
    Linux 的 strace 命令
    NTFS系统的ADS交换数据流
    Git和.gitignore
    GIT常用命令
    OSChina码云试用
    tcpdump用法
    linux网卡混杂模式
  • 原文地址:https://www.cnblogs.com/tianhonghui/p/2608110.html
Copyright © 2020-2023  润新知