MvvmCross TipCalc - 步骤 6:创建 WPF UI
MvvmCross v3 - Hot Tuna 的 TipCalc 教程的步骤 6。
介绍
本文是MvvmCross
v3 - Hot Tuna!TipCalc
教程的第6步!
迄今为止...
我们开始的目标是创建一个应用程序,以帮助计算在餐厅应该留下多少小费。
我们计划基于此概念创建一个 UI

为了实现这一点,我们构建了一个“Core
”可移植类库项目,其中包含
- 我们的“业务逻辑” - `ICalculation`
- 我们的 `ViewModel` - `TipViewModel`
- 我们的 App,它包含了应用的连接逻辑,包括启动指令
我们已经有了三个用户界面 - 分别是Xamarin.Android
、Xamarin.iOS
和WindowsPhone

对于我们的下一个项目,让我们转向Windows桌面 - 通过WPF - Windows Presentation Foundation。
在这里,我们将像为Core、Android、iOS、WindowsPhone和WindowsStore项目一样,从头开始构建一个新项目。
显然,要使用WPF,您需要在PC上使用Visual Studio。
创建新的WPF项目
向您的解决方案添加一个新项目 - 一个名为TipCalc.UI.Wpf
的“WPF应用程序”。
重要提示 - 确保这是至少.NET 4.5 - 因为这是PCL Profile104所需版本 - 再见,XP!
在这个项目中,您将找到常规的WPF应用程序结构
- 包含“AssemblyInfo”文件的“Properties”文件夹,一些资源和一个设置文件
- “App.Config”配置文件
- App.Xaml“应用程序”对象
- 定义此应用程序默认窗口的MainWindow.Xaml和MainWindows.Xaml.cs文件
保留MainWindow.xaml
我们确实希望这个应用程序有一个MainWindow
。 " align="top" src="https://codeproject.org.cn/script/Forums/Images/smiley_smile.gif" />
添加引用
添加对 CoreCross 和 MvvmCross - PCL 版本的引用
为新项目添加对可移植库的引用
- Cirrious.CrossCore.dll
- 核心接口和概念,包括跟踪、IoC 和插件管理
- Cirrious.MvvmCross.dll
- Mvvm 类 - 包括视图和 ViewModel 的基类
通常,这些文件会位于类似 {SolutionRoot}/Libs/Mvx/Portable/ 的文件夹路径中。
添加对MvvmCross - WPF特定版本的引用
为WPF特定库的新项目添加引用
- Cirrious.MvvmCross.Wpf.dll
这扩展了其PCL对应项的功能,并增加了WPF特定的内容。
通常,这可以在一个类似于{SolutionRoot}/Libs/Mvx/Wpf/的文件夹路径中找到。
注意: MvvmCross使用来自System.Windows.Interactivity的简单行为 - 因此,为了构建MvvmCross Wpf应用程序,您需要安装Expression Blend。
添加对TipCalc.Core.csproj的引用
为您的TipCalc.Core
项目添加引用 - 我们在上一步创建的项目,其中包括
- 您的
Calculation
服务 - 您的
TipViewModel
- 您的 App 连接
添加 Setup 类
正如我们在Android、iOS、WP和WindowsStore构建过程中所说,每个MvvmCross UI项目都需要一个Setup类。
这个类位于我们 UI 项目的根命名空间(文件夹)中,负责初始化 `MvvmCross` 框架和你的应用程序,包括
- 控制反转 (IoC) 系统
MvvmCross
数据绑定- 您的 App 及其
ViewModel
集合 - 您的 UI 项目及其
View
集合
大部分功能已自动为您提供。在您的WPF UI项目中,您只需要提供
- 您的 App - 您与业务逻辑和
ViewModel
内容的连接
对于TipCalc
,Setup.cs中只需要这些:
using System.Windows.Threading;
using Cirrious.MvvmCross.ViewModels;
using Cirrious.MvvmCross.Wpf.Platform;
using Cirrious.MvvmCross.Wpf.Views;
namespace TipCalc.UI.Wpf
{
public class Setup : MvxWpfSetup
{
public Setup(Dispatcher uiThreadDispatcher,
IMvxWpfViewPresenter presenter) : base(uiThreadDispatcher, presenter)
{
}
protected override IMvxApplication CreateApp()
{
return new Core.App();
}
}
}
修改App.xaml.cs以使用Setup
还有其他生命周期和显示技术可用于编写WPF应用程序。
然而,在这里我们将只使用“一个窗口带一个视图”的方法。
为了实现这一点,在WPF App类中添加一些行来
-
提供一个
private
标志,用于确定设置是否已完成private bool _setupComplete = false;
-
执行设置 - 使用基于
MainWindow
的Simple Presenterprivate void DoSetup() { var presenter = new MvxSimpleWpfViewPresenter(MainWindow); var setup = new Setup(Dispatcher, presenter); setup.Initialize(); var start = Mvx.Resolve<IMvxAppStart>(); start.Start(); _setupComplete = true; }
-
重写
OnActivated
事件以执行此启动protected override void OnActivated(System.EventArgs e) { if (!_setupComplete) DoSetup(); base.OnActivated(e); }
完成此操作后,您的App.xaml.cs可能看起来像
using System.Windows;
using Cirrious.CrossCore.IoC;
using Cirrious.MvvmCross.ViewModels;
using Cirrious.MvvmCross.Wpf.Views;
namespace TipCalc.UI.Wpf
{
public partial class App : Application
{
private bool _setupComplete = false;
private void DoSetup()
{
var presenter = new MvxSimpleWpfViewPresenter(MainWindow);
var setup = new Setup(Dispatcher, presenter);
setup.Initialize();
var start = Mvx.Resolve<IMvxAppStart>();
start.Start();
_setupComplete = true;
}
protected override void OnActivated(System.EventArgs e)
{
if (!_setupComplete)
DoSetup();
base.OnActivated(e);
}
}
}
添加您的 View
创建UserControl
创建一个Views文件夹。
在该文件夹中,添加一个新的“User Control (WPF)”并将其命名为TipView.xaml。
页面将生成
- TipView.xaml
- TipView.xaml.cs
将 TipView 变成 TipViewModel 的 MvvmCross 视图
打开TipView.cs文件。
将类更改为继承自MvxWpfView
。
public partial class TipView : MvxWpfView
为了将TipView
链接到TipViewModel
,创建一个public new TipViewModel ViewModel
属性 - 与您在Xamarin.Android
、Xamarin.iOS
、WindowsPhone
和WindowsStore
中一样。
public new TipViewModel ViewModel
{
get { return (TipViewModel) base.ViewModel; }
set { base.ViewModel = value; }
}
总而言之,这看起来是这样的
using Cirrious.MvvmCross.Wpf.Views;
using TipCalc.Core.ViewModels;
namespace TipCalc.UI.Wpf.Views
{
public partial class TipView : MvxWpfView
{
public new TipViewModel ViewModel
{
get { return (TipViewModel)base.ViewModel; }
set { base.ViewModel = value; }
}
public TipView()
{
InitializeComponent();
}
}
}
编辑 XAML 布局
双击XAML文件
这将在 Visual Studio 中打开 XAML 编辑器。
与WindowsPhone和WindowsStore一样,我在这里不会深入探讨如何使用XAML或进行Windows数据绑定。我假设大多数读者已经至少有一些XAML背景。
将根节点从
<UserControl
...
</UserControl>
to
<views:MvxWpfView
xmlns:views="clr-namespace:Cirrious.MvvmCross.Wpf.Views;assembly=Cirrious.MvvmCross.Wpf"
...
</views:MvxWpfView>
为了添加我们的小费计算器的XAML用户界面,我们将添加与我们在WindowsStore示例中添加到ContentPanel grid
中的XAML完全相同的XAML。这包括
- 一个
StackPanel
容器,我们将在其中添加- 一些
TextBlock
静态文本 - 用于
SubTotal
的绑定TextBox
- 用于
Generosity
的绑定Slider
- 用于
Tip
的绑定TextBlock
- 一些
这将产生如下完成的XAML
<views:MvxWpfView
xmlns:views="clr-namespace:Cirrious.MvvmCross.Wpf.Views;assembly=Cirrious.MvvmCross.Wpf"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="TipCalc.UI.Wpf.Views.TipView">
<StackPanel>
<TextBlock
Text="SubTotal"
/>
<TextBox
Text="{Binding SubTotal, Mode=TwoWay}"
/>
<TextBlock
Text="Generosity"
/>
<Slider
Value="{Binding Generosity, Mode=TwoWay}"
SmallChange="1"
LargeChange="10"
Minimum="0"
Maximum="100" />
<TextBlock
Text="Tip"
/>
<TextBlock
Text="{Binding Tip}"
/>
</StackPanel>
</views:MvxWpfView>
请注意,在XAML中,OneWay
绑定通常是默认的。
为了提供TwoWay
绑定,我们在绑定表达式中显式添加Mode
:例如,Value="{Binding Generosity,Mode=TwoWay}"
。
在设计器中,这将显示为

Wpf UI已完成!
此时,您应该能够运行您的应用程序。
当它启动时...您应该看到

这似乎工作得很完美,尽管您可能会注意到,如果您在 SubTotal TextBox
中编辑值,则其余的显示不会正确更新。
这是一个View的关注点 - 这是一个UI问题。所以我们可以在WPF UI代码中修复它 - 就像我们在WindowsPhone和WindowsStore示例中所做的那样。
继续...
我们还可以做更多的事情来让这个用户界面更美观,让应用更丰富……但对于这第一个应用程序,我们暂时就到这里。
实际上...这就是我们第一个应用程序的旅程的结束。
不久的将来,还会增加更多的步骤 - 一个用于Mac桌面,一个用于XBox,一个用于TV等 - 但现在,这是结束。
文章
- MvvmCross TipCalc - 步骤 1:创建核心可移植应用程序
- MvvmCross TipCalc - 第 2 步:创建 Android UI
- MvvmCross TipCalc - 第 3 步:创建 iOS UI
- MvvmCross TipCalc - 第 4 步:创建 Windows Phone UI
- MvvmCross TipCalc - 第 5 步:创建 Windows Store UI
- MvvmCross TipCalc - 步骤 6:创建 WPF UI
- MvvmCross TipCalc - 回顾
历史
- 2013 年 3 月 22 日 - 首次提交