MVVM ViewModel与View的交互

MVVM,你怎样关闭View?

image

最近用Prism写MVVM程序时遇到一个问题,如果希望在ViewModel中用代码将View关闭,应该怎么办呢?

在网上看了很多人的做法,有人把View传到ViewModel中作为一个属性,有人在ViewModel中定义一个事件,在View中响应这个事件。

但我不喜欢这些做法,因为这样不够“正宗”。我想,Prism这样一个这么大一个框架,里面肯定的解决办法。

找了很多官方资料,办法有了。

InteractionRequest

MVVM

没错,就是他了。在MVVM设计模式中,View产生的操作由Command传递到ViewModel,View上的数据显示则由 Data Binding 负责,而ViewModel对View的操作,则由InteractionRequest完成。

MVVM Close View Demo

下面,以从ViewModel关闭View为例子,做一个ViewModel对View进行操作的Demo。

image

程序功能很简单,点击Close按钮后把窗口关闭。

InteractionRequest<T>

InteractionRequest<T>是用在ViewModel里面的,我们看下代码。

using Microsoft.Practices.Prism.Commands;
using Microsoft.Practices.Prism.Interactivity.InteractionRequest;
using Microsoft.Practices.Prism.ViewModel;
using System;

namespace MVVMCloseView
{
    public class MainWindowViewModel : NotificationObject
    {
        public MainWindowViewModel()
        {
            this.CloseCommand = new DelegateCommand(new Action(Close));
            this.CloseRequest = new InteractionRequest<Notification>();
        }

        public DelegateCommand CloseCommand { get; set; }

        private void Close()
        {
            this.CloseRequest.Raise(new Notification() { Title = "App", Content = "Close" });
        }

        public InteractionRequest<Notification> CloseRequest { get; set; }
    }
}

这是ViewModel的代码,里面通过调用InteractionRequest的Raise方法,去通知View。参数里的Notification的两个属性,在这没什么用,仅仅为了告诉大家它有这两个属性而已,但在别的地方,比如我是要弹出一个MessageBox,这两个属性就有用了。

InteractionRequestTrigger

InteractionRequestTrigger是用在View里面的,这是View的代码。

<Window x:Class="MVVMCloseView.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:v="http://schemas.microsoft.com/expression/2010/interactions"
        xmlns:prism="http://www.codeplex.com/prism"
        xmlns:local="clr-namespace:MVVMCloseView"
        Title="MainWindow" Height="350" Width="525" x:Name="window">
    <Window.DataContext>
        <local:MainWindowViewModel/>
    </Window.DataContext>
    <i:Interaction.Triggers>
        <prism:InteractionRequestTrigger SourceObject="{Binding CloseRequest}">
            <v:CallMethodAction MethodName="Close" TargetObject="{Binding ElementName=window}"/>
        </prism:InteractionRequestTrigger>
    </i:Interaction.Triggers>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <TextBlock Text="MVVM Close View Demo" Foreground="Green" FontSize="24" Margin="10"/>
        <Button Content="Close" Grid.Row="1" FontSize="30" Width="200" Height="100" Command="{Binding CloseCommand}"/>
    </Grid>
</Window>

View里面给窗口加了一个附加属性,这个附加属性是在Blend SDK里面的(下载Blend + SketchFlow Preview for Microsoft Visual Studio 2012),里面,我们看到了InteractionRequestTrigger,InteractionRequestTrigger在View中响应来自ViewModel的InteractionRequest,(这个InteractionRequest是它的SourceObject属性,用Data Binding关联在ViewModel中的CloseRequest)上并执行它里面的Action,本例中的Action是调用窗口的Close方法,当然也可以用别的Action,甚至创建我们自己的Action。

关于MVVM

本文讨论的是进行MVVM开发中的问题,关于MVVM的基础知识,可以参考刘铁猛老师的 MVVM入门与提高 和Patterns & Practices的 Using the Model-View-ViewModel Pattern

作者:朱恒成(Hamson) 
出处:{Hamson} (http://www.cnblogs.com/hamson/) 
版权声明:本文的版权归作者与博客园共同所有。转载时须在明显地方注明本文的详细链接,否则作者将追究其法律责任。
 
 
分类: WPF.NETPrismMVVM
标签: WPFPrismMVVMBlend
原文地址:https://www.cnblogs.com/Leo_wl/p/2878834.html