Windows 8、MVVM Light 和 EventToCommand 入门





4.00/5 (3投票s)
现在 Windows 8 和 Visual Studio 都已发布 RTM 版本,我想为那些使用 MVVM Light 技能从 Windows Phone 开发过渡到 Windows 8 开发的人编写一个快速入门条目。
必备组件
您必须安装 Windows 8 和 Visual Studio 2012 才能使用此处提到的工具并完成本演练。
引言
Laurent Bugnion 是 MVVM Light 工具包的创建者,我和许多其他人一样,已经使用它进行 Windows Phone 开发有一段时间了。我正在将我的一个应用程序移植到 Windows 8,并希望将此工具包的知识带到新平台,希望它有一些新的增强功能和/或变化不大,这样我就可以直接上手。这正是我的想法。
Windows 8 RTM 版 MVVM Light 工具包该工具包的最新安装程序“MVVM Light Toolkit V4 RTM”可从 CodePlex 获取。根据 Laurent 的博客,它是与以前版本并排安装的
Windows 8 版 MVVM Light 是与标准 MVVM Light V3 或 V4 beta 版并排安装的。只需从 Codeplex 下载并运行 MSI。像往常一样,安装的最后一步会执行 Visual Studio 的“/setup”以更新项目模板缓存,不幸的是,最后一步可能需要很长时间。请耐心等待,不要在结束前取消!安装过程与 MVVM Light 安装页面上描述的非常相似(除了还没有 VS11 的 NuGet 安装程序)。
以下 链接 总结了从以前版本移植的组件,但我在这里转述一下
- ObservableObject 包括所有引发
PropertyChanged
的方式。 - ViewModelBase 包括所有引发
PropertyChanged
的方式。 - Messenger 包括所有消息类型,除了
DialogMessage
(见下文)。 - RelayCommand 带或不带参数。
- SimpleIoc 很可能是第一个在 Windows 8 上运行的 IOC 容器。
我多么喜欢 SimpleIoc!它使添加新视图比 Windows Phone 版本容易得多。
有一些组件缺失,其中之一是 EventToCommand
,但是感谢我新认识的朋友 Joost van Schaik(点击此处查看他的博客),有一个解决方案,它作为一个 nuget 包提供,其中包含一些额外的行为功能,我鼓励您深入了解,但我至少会介绍他提供的 EventToCommand
功能。
入门
MVVM 项目模板
安装工具包后,您会发现 Visual Studio 2012 新建项目对话框中有一个新的项目模板可用
将项目命名为“MvvmLight_Walkthrough”并单击“确定”。
项目模板很简单,但添加了一些以前版本工具包中没有的新功能。在解决方案资源管理器中,您会注意到一个 Design 文件夹,其中包含一个名为 DesignDataService
的类。这是一个很棒的功能;默认模板中包含了设计数据类存储库。
其次,与过去版本的工具包一样,有正常的 ViewModelLocator
类,但在此版本中有一个新功能 - SimpleIoc
,一个容器类,如果您像我一样,除了 ViewModel 之外,所有其他东西都放在 DI 的容器中,除非您自己实现。
public class ViewModelLocator
{
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
if (ViewModelBase.IsInDesignModeStatic)
{
SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
}
else
{
SimpleIoc.Default.Register<IDataService, DataService>();
}
SimpleIoc.Default.Register<MainViewModel>();
}
/// <summary>
/// Gets the Main property.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
"CA1822:MarkMembersAsStatic",
Justification = "This non-static member is needed for data binding purposes.")]
public MainViewModel Main
{
get
{
return ServiceLocator.Current.GetInstance<MainViewModel>();
}
}
/// <summary>
/// Cleans up all the resources.
/// </summary>
public static void Cleanup()
{
}
}
最后,在 Model 文件夹中,Laurent 也很友善地包含了 IDataService
接口和 DataService
类,以在示例中展示如何使用实时和设计时数据模型。这些都在 ViewModelLocator 中连接起来,如上所示。
现在,如果我们简单地运行应用程序,您应该会得到以下结果,以确保一切正常!
您可能已经注意到,这与以前版本的项目模板测试并没有太大的不同
MainViewModel
ViewModel 到 View 的绑定与以前模型中的相同,ViewModelTemplate 没有明显的变化。需要注意的一点是,此版本包含了 RaisePropertyChanged
的所有选项,而在以前的版本中,您必须从 nuget 获取“预发布”版本才能使用它们。例如,内置模板包含以下内容
/// <summary>
/// The <see cref="WelcomeTitle" /> property's name.
/// </summary>
public const string WelcomeTitlePropertyName = "WelcomeTitle";
private string _welcomeTitle = string.Empty;
/// <summary>
/// Gets the WelcomeTitle property.
/// Changes to that property's value raise the PropertyChanged event.
/// </summary>
public string WelcomeTitle
{
get
{
return _welcomeTitle;
}
set
{
if (_welcomeTitle == value)
{
return;
}
_welcomeTitle = value;
RaisePropertyChanged(WelcomeTitlePropertyName);
}
}
值得注意的是,RaisePropertyChanged
使用的是字符串值,此版本中现在可用的选项之一是删除 WelcomeTitlePropertyName
变量,然后更改
RaisePropertyChanged(WelcomeTitlePropertyName);
to
RaisePropertyChanged(() => WelcomeTitle);
另一个好处是,模板还为将 IDataService
注入 ViewModel 的构造函数提供了连接。我们这些开发人员要么认为有人已经费力地完成了这些基础工作,要么认为这是在完成实际工作之前必须完成的枯燥工作。您可以在此处轻松地将其他依赖项放入构造函数中,然后只需通过将类型注册到 SimpleIoc 容器来添加 ViewModelLocator 构造函数中的映射。
public MainViewModel(IDataService dataService) { _dataService = dataService; _dataService.GetData( (item, error) => { if (error != null) { // Report error here return; } WelcomeTitle = item.Title; }); }
接下来呢?
这里有一个简单的例子,向 MainPage 添加一些内容,并看看我们如何导航到第二个视图。我不会用向页面添加控件的细节来烦您,但这是完成后的页面应该有的样子。
事件到命令
现在,我们只需向提交按钮添加一个提示。但是等等,我的 EventToCommand 在哪里?当然,按钮有一个 Command 属性,您可以将其设置为 ViewModel 中的 ICommand,一切都很好。但是,WinRT 和第三方控件中有很多控件没有该属性。因此,为了简单起见,我将使用此控件,并将 EventToCommand 重新放入您的工具箱,或者我应该说您的 Joostbox。
前往 nuget!
我遇到过一个问题,在移植我正在开发的一个应用程序时,我正在寻找行为,但在 Blend 中找不到那些该死的行为,所以我去了 nuget 并进行了一些搜索,但没有发现任何让我感兴趣的东西。然后我遇到了 Joost van Schaik(点击此处查看他的博客)和他的 WinRTBehaviors 库,碰巧我在他上传 Win8nl 的 nuget 包时遇到了他。现在这是一个行为包,最初是一个 Windows Phone 7 库,现在它正在朝着自己的方向发展,现在包含一些 Windows 8 特定的东西(根据 nuget)。所以让我们快速安装它。通过在 Nuget 包管理器控制台中键入以下内容或在包浏览器中搜索 Win8nl 来安装该包。
PM> Install-Package Win8nl
它将添加库和必要的依赖项到项目中,其中包括 WinRTBehaviors。有关其他行为的更多信息,请查看 Joost 的博客。
添加 EventToCommand
首先,让我们添加对 XAML 页面的引用
xmlns:WinRtBehaviors="using:WinRtBehaviors" xmlns:Win8nl_Behavior="using:Win8nl.Behaviors"
接下来,找到按钮控件并在按钮 XAML 中添加以下内容
<Button x:Name="btnSubmit" Content="Submit" FontFamily="{StaticResource MyFont}" FontSize="{StaticResource MyFontSize}" HorizontalAlignment="Center" Margin="0,20,0,0"> <WinRtBehaviors:Interaction.Behaviors> <Win8nl_Behavior:EventToCommandBehavior Event="Tapped" Command="AreYouSureCommand" CommandParameter="{Binding MyName}"/> </WinRtBehaviors:Interaction.Behaviors> </Button>
现在,打开 MainViewModel.cs 代码,我们可以在此处为新行为添加命令,当按钮被点击时。
像往常一样,Command 属性期望一个 ICommand
,将以下代码添加到 MainViewModel 并返回 RelayCommand
的新实例以执行您希望的任何行为。在此示例中,我只是弹出一个小窗口以显示用户在 myName
TextBox 中输入的任何内容。
public ICommand AreYouSureCommand
{
get
{
return new RelayCommand<string>((p) =>
{
var msg = new MessageDialog(string.Format("Hi there {0}", p));
msg.ShowAsync();
});
}
}
在此处查看结果
这就是 Windows 8 MVVMlight 的 EventToCommand
!
WinRTBehaviors 库中还有更多行为您应该利用,对我来说,最值得注意的是 FlipViewPanoramaBehavior
和 NavigationService
被移植到 Windows 8。
在我的博客 TattooCoder.com 上查看更多 MVVM Light 相关文章和其他内容