65.9K
CodeProject 正在变化。 阅读更多。
Home

在 XAML 中使用 EventTrigger 进行 MVVM – 无代码隐藏

2010 年 11 月 6 日

CPOL

8分钟阅读

viewsIcon

282509

downloadIcon

7501

在本文中,我将向您展示如何触发 Triggers 来调用 ViewModel 中存在的一些方法,而不是在代码隐藏文件中编写。阅读更多内容以了解它。

引言

我看到人们在 MVVM 框架中工作时编写了大量的代码隐藏。他们在 xaml.cs 文件中的大量代码实际上给设计师带来了修改 XAML 中任何内容的麻烦。为什么会这样?因为很多人不知道如何使用 Triggers 来调用 MVVM 方法来完成他们的业务需求。

Michael Washington 有一篇关于 DataTrigger 的精彩 文章,可以减少代码隐藏文件。它确实减少了 MVVM 面临的普遍问题。另外,我们需要做一些额外的事情来减少代码隐藏。

在本文中,我将向您展示如何触发 Triggers 来调用 ViewModel 中存在的一些方法,而不是在代码隐藏文件中编写。阅读更多内容以了解它。

设置 MVVM 项目

首先,我们需要设置 MVVM 项目。创建一个 Silverlight 项目,并从解决方案中删除“MainPage.xaml”及其代码隐藏。现在在项目中创建名为“Models”、“Views”和“ViewModels”的 MVVM 文件夹结构。在 Views 文件夹中创建一个名为“MainView”的新 XAML 页面。这也会在同一文件夹中为您创建相应的代码隐藏文件(“MainView.xaml.cs”)。现在在 ViewModels 文件夹中创建一个名为“MainViewModel”的 ViewModel

看看我们项目的 MVVM 文件夹结构

image

确保在 App.xaml.cs 文件中将 RootVisualMainPage 更改为 MainView。构建项目以确保没有错误。如果遇到任何问题,请立即修复。

添加外部库

现在我们需要 2 个 DLL 程序集来使用 EventTrigger,它们如下所示:

  1. System.Windows.Interactivity.dll
  2. Expression.Samples.Interactivity.dll

从附加的 zip 文件下载库并将其提取到本地驱动器。在我们的例子中,我们将把它们放在解决方案中。将库复制到一个名为“ExternalAssemblies”的文件夹,并确保从项目中排除该文件夹。

image

实际上,如果您将库复制到正确的位置,以便您的项目可以访问它们,那么上述步骤不是必需的。

image

现在右键单击项目或引用文件夹。将弹出一个上下文菜单,如下所示。单击“添加引用”以显示“添加引用”对话框。

image

现在,浏览到您存放 DLL 的程序集文件夹,并将它们添加到您的项目中。

image

单击“添加”继续。

image

您将看到程序集已添加为项目的引用。请看以下截图。

image

再次构建解决方案以检查是否存在任何构建错误,并根据需要进行解决。

创建基本视图和 ViewModel

让我们修改视图,其中包含一些简单的控件。我们添加一个 TextBox,可以在其中插入 Employee 名称,以及一个带有单击事件的按钮,用于显示一些消息。现在不要在其中添加任何单击事件。我们稍后会添加它们。

image

一旦您的上述视图准备就绪,请跳转到 ViewModel 添加一些属性。我们添加一个类型为 stringEmployeeName。添加一个简单的 `MessageBox` 方法来显示一些文本。

这是我们的示例 ViewModel

using System.Windows;

namespace MVVMEventTriggerDemo.ViewModels
{
    public class MainViewModel
    {
        public string EmployeeName { get; set; }
        public string Country { get; set; }

        public void HandleShowMessage()
        {
            MessageBox.Show("Hello " + EmployeeName + ", 
			Welcome to EventTrigger for MVVM.");
        }
    }
}

一旦您的 ViewViewModel 准备就绪,请构建并运行应用程序以查看我们将要演示的用户界面。

将 ViewModel 绑定到 View

现在我们的 ViewModel 已经准备就绪,是时候将 ViewModel 绑定到 View 了。请记住,您的 View 知道它的 ViewModel 是什么,但反之则不然。您的 ViewModel 不应引用 view

让我们为 View 添加 ViewModel。打开您的 MainView.xaml 页面。在 usercontrol 标签中,添加 ViewModelxmlns 命名空间,如下面的图所示。

image

添加 xmlns 命名空间后,创建 UserControl.Resources 标签,如下所示,并将 ViewModel 添加为页面的静态资源。

image

LayoutRoot Grid 的 DataContext 设置为我们刚刚添加的 Static Resource “mainViewModel”。

image

现在将名为“EmployeeName”的 ViewModel 属性绑定到 TextBox,并将 Mode 设置为“TwoWay”,这样,如果最终用户更改 TextBox 中的文本,它将自动更新 ViewModel 中的属性。

设置 Triggers

现在是时候为按钮设置 XAML 的 Trigger 了。为两个程序集添加 xmlns 命名空间。首先添加“System.Windows.Interactivity”的命名空间,如下面的屏幕截图所示。

image

现在在 XAML 页面中添加另一个命名空间“Expression.Samples.Interactivity”。请看图。

image

既然我们的 xmlns 命名空间已成功导入,现在我们将 Trigger 添加到按钮。修改 button 标签,使其现在被编码为一个 Container。在标签内,添加 Interaction.Triggers 标签,如下所示。

image

Interactivity 命名空间添加 EventTrigger,并将 EventName 设置为“Click”。如果要使用不同的事件,可以相应地修改它。

在 Event Trigger 中导入 Samples Interaction,您会看到有许多方法可用于在 XAML 内部执行各种操作。您可以调用 ViewModel 中的 DataMethod,可以更改 FrameworkElement 的状态到另一个有效状态,可以调用 DataCommand,暂停媒体,显示消息等。

让我们做其中一些,以便您轻松理解该功能。首先添加一个 CallDataMethod 事件。

image

现在将方法名设置为我们 ViewModel 中的方法,即“HandleShowMessage”。您将拥有以下代码。

image

稍后,我会分享完整的代码供您复制。另外,整个解决方案都已附加供您下载。好吧,回到实际主题。打开您的代码隐藏文件。在那里您会看到文件是完全空的。 Confused smile (困惑!!!)是的,它是完全空的。它只有一个构造函数和一个对 InitializeComponent() 方法的调用,这对于任何 Silverlight 页面都是必需的。因此,我们可以将其视为一个空类。您会发现没有编写额外的代码来引发和实现 Button Click 事件。

image

一个非常整洁的代码隐藏文件,对吧?现在构建解决方案并按 F5 运行应用程序。您将在浏览器窗口中看到加载的应用程序。在 TextBox 中输入一个名称,然后单击“Show Message”按钮。天哪!!!按钮正在将事件触发到 ViewModel,并且 MessageBox 已弹出到屏幕,其中包含已输入并绑定到 EmployeeName 属性的文本。

image

让我们稍微修改一下 XAML,并将 ShowMessageBox 交互事件添加到 Trigger 中,并设置正确的 CaptionMessageMessageBoxButton。请看下图中的代码。

image

您认为如果我们运行应用程序,它会起作用吗?让我们看看… Open-mouthed smile 现在再次运行应用程序。您将在屏幕上看到加载的相同应用程序。在 TextBox 中输入一个名称,然后单击“Show Message”按钮。您将看到如下所示的消息框弹出到屏幕。

image

单击“OK”。哇,另一个消息框!!!是的,这是我们刚刚在 XAML 页面中添加的消息框,具有确切的标题和消息字符串。消息框不在我们的代码隐藏中,也不在 viewmodel 中。它是库提供的默认消息框,带有自定义文本。

image

那么,您怎么看?我们只能使用 EventTrigger 为 MVVM 调用数据方法吗?如果我们想更改 UI 元素的某个属性,该怎么做?在这种情况下,我们是否必须在 CodeBehind 中编写,还是必须在 ViewModel 中创建一个属性并将其绑定到 UI?

不,不用担心。您不必为此做任何事情。您只需要调用 SetProperty 来自示例交互库,并附带正确的参数。请看代码。

image

在这里,我将 TargetName 设置为 LayoutRoot,即主 Grid。我们想将 GridBackground 颜色从 White 更改为 PaleGoldenrod。因此,为此设置值。

现在,再次运行应用程序并单击“Show Message”。您将在屏幕上看到消息。单击“OK” Surprised smile。背景颜色已更改,无需在代码隐藏中编写任何内容!!!

image

如此简单,对吧?那么,为什么您要在 xaml.cs 文件中编写代码?立即停止并迁移到正确的 MVVM 模式。

这是完整的 XAML 代码供您参考。

<UserControl x:Class="MVVMEventTriggerDemo.Views.MainView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:viewModel="clr-namespace:MVVMEventTriggerDemo.ViewModels"
    xmlns:i="clr-namespace:System.Windows.Interactivity;
			assembly=System.Windows.Interactivity"
    xmlns:si="clr-namespace:Expression.Samples.Interactivity;
			assembly=Expression.Samples.Interactivity"
    Height="132" Width="250">
    <UserControl.Resources>
        <viewModel:MainViewModel x:Key="mainViewModel"/>
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" Background="White" 
		DataContext="{StaticResource mainViewModel}">
        <TextBox Text="{Binding EmployeeName, Mode=TwoWay}" 
		Width="200" Height="30" Margin="28,24,22,78" />
        <Button Content="Show Message" Width="100" Height="25" Margin="128,70,22,37">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="Click">
                    <si:CallDataMethod Method="HandleShowMessage"/>
                    <si:ShowMessageBox Caption="Thank you"
                                       Message="Thanks for trying the Example"
                                       MessageBoxButton="OK"/>
                    <si:SetProperty TargetName="LayoutRoot" 
			PropertyName="Background" Value="PaleGoldenrod"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Button>
    </Grid>
</UserControl>

整个解决方案也可以作为可下载的 zip 文件提供。

结束语

尝试在您的环境中运行它,并自己创建一些示例。完成此操作后,您将熟悉 MVVM 模式,然后停止在 xaml.cs 文件中编写代码。将所有内容移至 ViewModel 并使用属性将数据绑定到视图。直接从 XAML 调用 viewmodel 方法,并从视图引发必要的事件。

希望这将帮助您以 MVVM 的方式理解事件触发。请不要停止在此处分享您的反馈和建议。如果您有任何问题,请告诉我。我会尽快回复您。

另外,请阅读 Michael Washington 分享的 文章。这将为您阐明数据触发器概念。现在尽情享受 MVVM 的乐趣。祝您一切顺利… Thumbs up

© . All rights reserved.