zoukankan      html  css  js  c++  java
  • MVVM中间接使用事件(命令)

    在使用MVVM模式时, 按照模式的规则是尽量不直接使用事件. 所以对于以前一直使用事件模式的同行来说确实有点头疼. 还好微软给我们提供了几种间接使用事件(命令)的方法, 下面我就来看看这几种方法:

    ICommand

    ICommand定义了一个接口, 使用它可以轻松的将实现ICommand的接口的命令绑定到包含命令(Command)的控件上(例如Button.Command), 在.net framework库中实现的这个接口的类不是很多, 我所知道的两个: RoutedCommand 和 RoutedUICommand, 而且这两个使用起来比较麻烦, 在这里我就不谈了, 有兴趣的同行可以研究一下. 那么, 除了上述的两个类以外还有自定义类实现ICommand和Prism的DelegateCommand. 我们先看一下自定义的;

    1. 自定义命令

    MyCommand是实现ICommand接口的一个类. 在Execute方法中我们调用传入的Action(Action包含所要实现的功能的方法), IsEnabledExecute是自定义的一个bool类型, 通过设置该值可以启用(禁用)ICommand所绑定到的控件的启用禁用状态.

    View Code

    定义好MyCommand后我们就可以使用了, 代码如下:

    View Code

    <!--XAML-->

    View Code

    首先定义了MvvmEventViewModel, 在MvvmEventViewModel中实例化了MyCommand, 将Button所在的界面或者用户控件的属性DataContext绑定上MvvmEventViewModel的实例, 最后直接在Button的Command属性上绑定MyCommandInstance;

    2.prism命令

    prism是微软的一个开源框架, 其为WPF(SL)而生, 自然也少不了MVVM模式的一些辅助类, 其中命令就是典型的辅助类. 在上面我们是自定义命令, 其实在prism框架中已经提供了命令类, 那就是DelegateCommand, 该类还为泛型提供了支持; 不仅如此prism还提供了多个命令的绑定CompositeCommand, 为一个Button命令可以执行多个方法问题提供了廉价的解决方案.

    2.1. DelegateCommand 命令

    DelegateCommand 命令与我们上面自定义的命令一样, 都是可以绑定到Button的Command属性上, 使用该类少了几行代码, 多了一份省心和安全. 如果让我选择我会选择DelegateCommand类而摒弃自定义类, 因为它可以实现我们需要的功能, 所以就没必要再重造轮子.

    View Code

    <!--XAML-->

    View Code

    2.2.CompositeCommand 命令

    CompositeCommand 命令可以理解为一个命令组. 将ICommand注册到CompositeCommand中, 然后绑定在Command上, 就可以让Command触发注册到CompositeCommand的所有命令.

    2.2.1.定义一个CompositeCommand命令

    View Code

    2.2.2.使用CompositeCommand命令

    Comm.CompositeCommand.RegisterCommand(MyCommandInstance);

    Comm.CompositeCommand.RegisterCommand(MyDelegateCommandInstance);

    <!--XAML-->

    xmlns:comm="clr-namespace:Blogs.WPF"

    复制代码
    <Button Width="180"
    
                    Height="23"
    
                    Margin="0,0,7,0"
    
                    HorizontalAlignment="Left"
    
                    Command="{x:Static comm:Comm.CompositeCommand}"
    
                    CommandParameter="DelegateCommand"
    
                    Content="CompositeCommand Button" />
    复制代码

    将我们刚才定义的两个命令MyCommandInstance和MyDelegateCommandInstance注册到Comm.CompositeCommand中, 然后在一个Button上绑定 comm:Comm.CompositeCommand 此时我们单击CompositeCommand Button时发现触发了两个命令. 同样的我们也可以使用UnregisterCommand卸载命令.

    2.3.将其他事件绑定到ICommand上

    在上述的例子中我们只是在Button的Command属性上绑定ICommand, 那么对于一些特殊事件(如Loaded, MouseDown, MouseUp)我们该怎么处理呢? 网上也有一些传统的方法, 将控件直接传送到VM中, 使用+=创建特殊的事件. 其实还有更好的办法, 那就是System.Windows.Interactivity.dll 组件.

    在你的项目中引入System.Windows.Interactivity.dll, 然后在页面中添加如下代码: xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

    OK, 现在就让我们就来使用这两个组件, 代码简单, 请看:

    复制代码
    public DelegateCommand LostFocusCommand { get; private set; }
     
    LostFocusCommand = new DelegateCommand(LostFocusMethod);
     
     
     
    private void LostFocusMethod()
     
    {
     
    MessageBox.Show("捕获到了.嘿牟嘿牟.");
     
    }
    复制代码
    复制代码
    <TextBlock Background="OrangeRed" Text="左键按下时我能捕获到">
     
    <i:Interaction.Triggers>
     
    <!-- 当单击鼠标左键按下时 -->
     
    <i:EventTrigger EventName="MouseLeftButtonDown">
     
    <i:InvokeCommandAction Command="{Binding LostFocusCommand}" />
     
    </i:EventTrigger>
     
    </i:Interaction.Triggers>
     
    </TextBlock>
    复制代码

    注: 名字起的有点不对应. 不想改了, 大家知道就可以.

    以上是使用System.Windows.Interactivity.dll组件可以将事件直接绑定到命令上, 但是我觉得这样麻烦, 如果可以直接使用事件岂不是更爽. 呵呵. 能提出问题就能解答问题. 我们再看另一个组件 Microsoft.Expression.Interactions.dll .

    同样的, 项目中引用 Microsoft.Expression.Interactions.dll

    添加命名空间

    复制代码
    xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
     
    <UserControl>
     
    <i:Interaction.Triggers>
     
    <i:EventTrigger EventName="Loaded">
     
    <ei:CallMethodAction MethodName="View_Loaded" TargetObject="{Binding}" />
     
    </i:EventTrigger>
     
    </i:Interaction.Triggers>
     
    </UserControl>
    复制代码

    注意: 在多层项目中只要你使用System.Windows.Interactivity.dll, Microsoft.Expression.Interactions.dll 这两个组件,就必须在启动层中引用这两个DLL, 否则报错.

     源码地址: 点击下载

    http://www.cnblogs.com/ynbt/archive/2013/01/03/2842847.html

  • 相关阅读:
    [Luogu P3626] [APIO2009] 会议中心
    杭电 1869 六度分离 (求每两个节点间的距离)
    杭电 1874 畅通工程续 (求某节点到某节点的最短路径)
    最短路径模板
    杭电 2544 最短路径
    POJ 1287 Networking (最小生成树模板题)
    NYOJ 1875 畅通工程再续 (无节点间距离求最小生成树)
    POJ 2485 Highways (求最小生成树中最大的边)
    杭电 1233 还是畅通工程 (最小生成树)
    杭电 1863 畅通工程 (最小生成树)
  • 原文地址:https://www.cnblogs.com/tianciliangen/p/5013168.html
Copyright © 2011-2022 走看看