Windows Universal 应用 – Tip Calculator

简介:

 以下内容取材于 Bob Tabor 的课程《Windows Phone 8.1 Development for Absolute Beginners》,链接地址为:http://www.microsoftvirtualacademy.com/training-courses/windows-phone-8-1-development-for-absolute-beginners

 

前言

    Universal App是一种跨平台的应用开发,目前主要面向Windows和Windows Phone设备。这里,我们会设计并完成一个Universal的Tip Calculator应用程序,该应用程序可以部署到Windows Phone手机上或者是Windows设备中。

 

1. 应用背景

    Tip Calculator,这个应用程序的灵感来自于外出就餐,老外一般有给服务员付小费的习惯,而小费该付多少一般是根据服务员的服务质量来的。本应用程序设计的小费规则是这样的,服务一般付10%,服务较好18%,服务完美25%。

 

2. 项目创建

    首先,我们需要创建一个应用程序,选择Templates > Visual C# > Store Apps > Universal Apps,选择Blank App (Universal Apps),命名为TipCalculatorUniversal,点击确定。

image

    工程创建完成以后,我们查看解决方案浏览器,发现以工程名称为开头的三个项目:Windows、Windows Phone和Shared。

image

    Windows和Windows Phone的工程在XAML布局上有所不同,原因是部分控件在不同的平台上有所差异。如果是两个平台上都能够用到的类和方法,我们可以放到Share项目中。在本应用中,把Tip.cs文件放到Shared项目中,在Windows和Windows Phone的工程中引用它。

3. Shared项目设计

    我们在Shared项目中,点击右键,添加新的文件:

image

    在对话框中,选择类,命名为Tip.cs,点击添加。

image

    在Tip.cs文件中加入以下代码,要注意两点,首先,设置Tip类为公共的。其次,创建三个属性,BillAmount, TipAmount 和 TotalAmount

public class Tip

{

    public string BillAmount { get; set; }

    public string TipAmount { get; set; }

    public string TotalAmount { get; set; }

}

    接下来,设置构造函数,将每个属性值初始化为空字符串。

public Tip()

{

    this.BillAmount = String.Empty;

    this.TipAmount = String.Empty;

    this.TotalAmount = String.Empty;

}

    接下来,创建一个计算小费的方法:

public void CalculateTip(string originalAmount, double tipPercentage)

{

    double billAmount = 0.0;

    double tipAmount = 0.0;

    double totalAmount = 0.0;

    if (double.TryParse(originalAmount.Replace('$', ' '), out billAmount))

    {

        tipAmount = billAmount * tipPercentage;

        totalAmount = billAmount + tipAmount;

    }

    this.BillAmount = String.Format("{0:C}", billAmount);

    this.TipAmount = String.Format("{0:C}", tipAmount);

    this.TotalAmount = String.Format("{0:C}", totalAmount);

}

    在这个方法中,originalAmount和tipPercentage这两个关键的内容作为传入参数,在计算得到小费和总价以后,存入类的公共属性中。注意,我们这里使用了double.TryParse()方法,如果用户输入了非数字的值,就会返回异常。

 

 

 

4. Windows Phone 项目设计

    现在,我们来看看Windows Phone的项目,在MainPage.xaml文件的Gird中加入以下行定义:

<Grid.RowDefinitions>

    <RowDefinition Height="50" />

    <RowDefinition Height="100" />

    <RowDefinition Height="*" />

</Grid.RowDefinitions>

    第一行和第二行分别用来显示应用程序名称和应用提示,如:

<TextBlock Margin="20, 0, 20, 0"

    Grid.Row="0"

    Style="{StaticResource TitleTextBlockStyle}">

    Tip Calculator

</TextBlock>

<TextBlock Margin="20, 0, 20, 0"

    Grid.Row="1"

    Style="{StaticResource TitleTextBlockStyle}"

    FontSize="48">

    Enter the Bill Amount

</TextBlock>

    接下来,我们在第三个行中添加一个StackPanel,占据整个剩余的空间。往StackPanel中添加控件如下:

<StackPanel Name="myStackPanel" Grid.Row="2" Margin="20, 0, 20, 0">

    <TextBlock HorizontalAlignment="Left"

        TextWrapping="Wrap"

        Text="Bill Amount"

        FontSize="24"/>

    <TextBox Name="billAmountTextBox"

        Text="$0.00"

        TextAlignment="Right"

        HorizontalAlignment="Left"

        TextWrapping="Wrap"

        VerticalAlignment="Top"

        InputScope="Number"

        Width="100"

        FontSize="24"

        LostFocus="amountTextBox_LostFocus"

        TextChanged="billAmountTextBox_TextChanged"

        GotFocus="amountTextBox_GotFocus" />

</StackPanel>

    在上面的代码中,billAmountTextBox允许用户输入账单上的总价,它是计算小费的基础。接下来,添加一个TextBlock和一系列RadioButtons,可以让用户选择服务的质量,以计算小费:

<TextBlock HorizontalAlignment="Left"

    TextWrapping="Wrap"

    Text="Percent To Tip:"

    VerticalAlignment="Top"

    FontSize="24"

    Margin="0,20,0,0"/>

<RadioButton Content="10% - Horrible Service"

    Tag="0.1"

    GroupName="percentRadio"

    Click="RadioButton_Click" />

<RadioButton Content="18% - Acceptable Service"

    Tag="0.18"

    GroupName="percentRadio"

    IsChecked="True"

    Click="RadioButton_Click" />

<RadioButton Content="25% - Great Service"

    Tag="0.25"

    GroupName="percentRadio"

    Click="RadioButton_Click" />

    注意,我使用了RadioButton的Tag属性,用来表示计算小费的百分比。这样的话,我可以不使用Switch语句,而直接获取Tag属性,计算小费。0.1表示10%,0.18表示18%,0.25表示25%。

    接下来,我们需要显示计算小费的结果,加入如下两个Textblock:

<TextBlock HorizontalAlignment="Left"

    TextWrapping="Wrap"

    Text="Amount to Tip:"

    FontSize="24"

    Margin="0,20,0,0" />

<TextBlock Name="amountToTipTextBlock"

    HorizontalAlignment="Left"

    TextWrapping="Wrap"

    VerticalAlignment="Top"

    Text="$0.00"

    FontSize="36" />

    最后,显示包含了小费和账单的总价,这个是我用信用卡付费的最后价格:

<TextBlock HorizontalAlignment="Left"

    TextWrapping="Wrap"

    VerticalAlignment="Top"

    Text="Total Bill:"

    FontSize="24"

    Margin="0,20,0,0" />

<TextBlock x:Name="totalTextBlock"

    HorizontalAlignment="Left"

    TextWrapping="Wrap"

    VerticalAlignment="Top"

    Text="$0.00"

    FontSize="36" />

    billAmountTextBox和RadioButton控件包含了一系列我们需要处理的事件。例如,当用户点击billAmountTextBox来输入账单时,我们需要首先清空已有的内容。在用户编辑数字以后,我们需要计算小费和总价。在用户的焦点移出billAmountTextBox时,我们给数字添加必要的美元符。接着,我们通过在XAML编辑器中相应的事件上点击右键,选择go to definition,创建对应的事件处理函数。

image

    在对应的cs文件中,创建的事件处理函数如下

image

    在后台代码中,我们创建一个Tip类的对象,并且在MainPage的构造函数中创建这个对象的实例:

image

    另外,我们在performCalculation()方法中,调用Tip类的CalculateTip方法计算所需要的小费和总帐单。

private void performCalculation()

{

    var selectedRadio = myStackPanel.Children.OfType<RadioButton>().FirstOrDefault(r => r.IsChecked == true);

    tip.CalculateTip(billAmountTextBox.Text, double.Parse(selectedRadio.Tag.ToString()));

    amountToTipTextBlock.Text = tip.TipAmount;

    totalTextBlock.Text = tip.TotalAmount;

}

    该方法的第一行是使用了LINQ语句检查用户选择的RadioButton;这种方法的优点在于,加入一个新的RadioButton控件,我们不需要增加新的代码去完成这个判断,但如果使用Switch语句就不一样了。

    在获得了用户选择的RadioButton后,就可以调用Tip类的CalculateTip方法进行计算。最后将计算所得的结果赋值给相应的控件显示就可以了。

    另外,什么时候需要执行这个performCalculation函数呢?首先,当用户输入新的账单时,即在(billAmountTextBox_TextChanged)这个事件被触发时;其次是用户选择不同的小费比例时,即在(RadioButton_Click)事件被触发时。

private void billAmountTextBox_TextChanged(object sender, TextChangedEventArgs e)

{

    performCalculation();

}

private void RadioButton_Click(object sender, RoutedEventArgs e)

{

    performCalculation();

}

    这样,我们就可以调试应用程序了。但是仍存在一些不便之处。如,当我点击Bill Amount TextBox控件输入内容时,该控件就应该自动清空上次我输入的内容,而不应该由我自己手动清除。

image

    其次,在输入完毕内容以后,我希望在前面加上美元符。

image

    为了实现这两个功能,我们可以通过下面的方式来做。

    首先,在amount TextBox获得焦点时,我们来清空其内容:

private void amountTextBox_GotFocus(object sender, RoutedEventArgs e)

{

    billAmountTextBox.Text = "";

}

    现在,再一次调试程序,你会发现,点击该TextBox时,会自从清空。

image

    第二,为了使得输入的内容后加上美元符,我在它失去焦点时,调用Tip类的CalculateTip()方法,

private void amountTextBox_LostFocus(object sender, RoutedEventArgs e)

{

    billAmountTextBox.Text = tip.BillAmount;

}

    其调试结果如下:

image

    注意,默认是Windows项目作为Start Up项目,我们要把它修改成Windows Phone的项目作为启动项目,可以在Windows Phone项目上点击右键,选择"Set as Start Up Project". 这样就可以了。

image

5. Windows 项目设计

    为了测试方便,我又重新把Windows项目设置为Start Up Project,方法和上面的一样,接下来,打开Windows项目的MainPage.xaml文件,预览如下:

image

    下面我们来看一下,在已有的Phone的界面设计的基础上,完成Windows的项目是多么容易。那么,首先我把Phone当中的MainPage.xaml中的页面布局代码拷贝过来,可以看到如下的效果:

image

    虽然我们的界面上还有很多的空余空间,但是大家可以发现,我们在Phone中的xaml控件,在这里同样可以使用。

    除了xaml代码,后台代码同样需要修改,主要是相关的事件处理程序。注意,后台代码的处理和上面的例子完全一样。

    完成以后,我们点击Simulator,开始调试。应用程序界面如下:

image

    因此,通过这次项目的内容我们发现,在这个Universal App中,使用了完全相同的XAML页面布局代码,使用了一个Tip类。当然,如果为了美观,我们当然可以拉伸Windows版本控件,以更加适合屏幕。因此,创建应用程序时,我建议把共同的逻辑、规则、数据获取和处理等内容放在Shared项目中,然后就可以在Windows和Windows Phone程序中引用它。这样我们就可以使得应用程序在多个不同的平台上使用。

参考链接:

•Windows Phone 8.1 Development for Absolute Beginners

•作者: Bob Tabor (Microsoft MVP)

•链接: http://www.microsoftvirtualacademy.com/training-courses/windows-phone-8-1-development-for-absolute-beginners

•源代码链接: http://aka.ms/absolutebeginnerwp81




      本文转自灵动生活博客园博客,原文链接:http://www.cnblogs.com/dearsj001/p/WindowsUniversalApp.html,如需转载请自行联系原作者

相关文章
|
4月前
|
Linux C++ Windows
【Azure 应用服务】Azure App Service(Windows)环境中如何让.NET应用调用SAP NetWeaver RFC函数
【Azure 应用服务】Azure App Service(Windows)环境中如何让.NET应用调用SAP NetWeaver RFC函数
【Azure 应用服务】Azure App Service(Windows)环境中如何让.NET应用调用SAP NetWeaver RFC函数
|
1月前
|
安全 前端开发 Windows
Windows Electron 应用更新的原理是什么?揭秘 NsisUpdater
本文介绍了 Electron 应用在 Windows 中的更新原理,重点分析了 `NsisUpdater` 类的实现。该类利用 NSIS 脚本,通过初始化、检查更新、下载更新、验证签名和安装更新等步骤,确保应用的更新过程安全可靠。核心功能包括差异下载、签名验证和管理员权限处理,确保更新高效且安全。
41 4
Windows Electron 应用更新的原理是什么?揭秘 NsisUpdater
|
2月前
|
XML 缓存 前端开发
Electron-builder 是如何打包 Windows 应用的?
本文首发于微信公众号“前端徐徐”,作者徐徐深入解析了 electron-builder 在 Windows 平台上的打包流程。文章详细介绍了 `winPackager.ts`、`AppxTarget.ts`、`MsiTarget.ts` 和 `NsisTarget.ts` 等核心文件,涵盖了目标创建、图标处理、代码签名、资源编辑、应用签名、性能优化等内容,并分别讲解了 AppX/MSIX、MSI 和 NSIS 安装程序的生成过程。通过这些内容,读者可以更好地理解和使用 electron-builder 进行 Windows 应用的打包和发布。
200 0
|
2月前
|
数据可视化 程序员 C#
C#中windows应用窗体程序的输入输出方法实例
C#中windows应用窗体程序的输入输出方法实例
56 0
|
4月前
|
Unix Linux Ruby
在windows和linux上高效快捷地发布Dash应用
在windows和linux上高效快捷地发布Dash应用
|
4月前
|
Linux iOS开发 开发者
跨平台开发不再难:.NET Core如何让你的应用在Windows、Linux、macOS上自如游走?
【8月更文挑战第28天】本文提供了一份详尽的.NET跨平台开发指南,涵盖.NET Core简介、环境配置、项目结构、代码编写、依赖管理、构建与测试、部署及容器化等多个方面,帮助开发者掌握关键技术与最佳实践,充分利用.NET Core实现高效、便捷的跨平台应用开发与部署。
405 3
|
4月前
|
PHP Windows
【Azure App Service for Windows】 PHP应用出现500 : The page cannot be displayed because an internal server error has occurred. 错误
【Azure App Service for Windows】 PHP应用出现500 : The page cannot be displayed because an internal server error has occurred. 错误
|
4月前
|
vr&ar C# 图形学
WPF与AR/VR的激情碰撞:解锁Windows Presentation Foundation应用新维度,探索增强现实与虚拟现实技术在现代UI设计中的无限可能与实战应用详解
【8月更文挑战第31天】增强现实(AR)与虚拟现实(VR)技术正迅速改变生活和工作方式,在游戏、教育及工业等领域展现出广泛应用前景。本文探讨如何在Windows Presentation Foundation(WPF)环境中实现AR/VR功能,通过具体示例代码展示整合过程。尽管WPF本身不直接支持AR/VR,但借助第三方库如Unity、Vuforia或OpenVR,可实现沉浸式体验。例如,通过Unity和Vuforia在WPF中创建AR应用,或利用OpenVR在WPF中集成VR功能,从而提升用户体验并拓展应用功能边界。
90 0
|
4月前
|
存储 开发者 C#
WPF与邮件发送:教你如何在Windows Presentation Foundation应用中无缝集成电子邮件功能——从界面设计到代码实现,全面解析邮件发送的每一个细节密武器!
【8月更文挑战第31天】本文探讨了如何在Windows Presentation Foundation(WPF)应用中集成电子邮件发送功能,详细介绍了从创建WPF项目到设计用户界面的全过程,并通过具体示例代码展示了如何使用`System.Net.Mail`命名空间中的`SmtpClient`和`MailMessage`类来实现邮件发送逻辑。文章还强调了安全性和错误处理的重要性,提供了实用的异常捕获代码片段,旨在帮助WPF开发者更好地掌握邮件发送技术,提升应用程序的功能性与用户体验。
77 0
|
4月前
|
C# Windows 监控
WPF应用跨界成长秘籍:深度揭秘如何与Windows服务完美交互,扩展功能无界限!
【8月更文挑战第31天】WPF(Windows Presentation Foundation)是 .NET 框架下的图形界面技术,具有丰富的界面设计和灵活的客户端功能。在某些场景下,WPF 应用需与 Windows 服务交互以实现后台任务处理、系统监控等功能。本文探讨了两者交互的方法,并通过示例代码展示了如何扩展 WPF 应用的功能。首先介绍了 Windows 服务的基础知识,然后阐述了创建 Windows 服务、设计通信接口及 WPF 客户端调用服务的具体步骤。通过合理的交互设计,WPF 应用可获得更强的后台处理能力和系统级操作权限,提升应用的整体性能。
130 0