声明

以下内容取材于 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,点击确定。

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

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

3. Shared项目设计

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

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

在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,创建对应的事件处理函数。

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

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

另外,我们在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控件输入内容时,该控件就应该自动清空上次我输入的内容,而不应该由我自己手动清除。

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

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

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

private void amountTextBox_GotFocus(object sender, RoutedEventArgs e)

{

billAmountTextBox.Text = "";

}

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

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

private void amountTextBox_LostFocus(object sender, RoutedEventArgs e)

{

billAmountTextBox.Text = tip.BillAmount;

}

其调试结果如下:

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

5. Windows 项目设计

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

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

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

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

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

因此,通过这次项目的内容我们发现,在这个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

Windows Universal 应用 – Tip Calculator的更多相关文章

  1. Unity3D移植Windows Universal App(Windows 8.1 及Windows Phone 8.1)版本遇到的坑

    移植的情况以及遇到的问题: 1.选用的版本是最新的Unity5.0. 2.全屏播放视频Handheld.PlayFullScreenMoview的路径必须是全路径,并且前面要加上"ms-ap ...

  2. 【Windows Universal Platform】只是学习笔记 - 开始

    我是初学,之前没有windows/windows phone的应用开发经验:开博的目的只是记录和督促自己学习. 心血来潮也好,或是个人喜好的原因,想学着自己开发APP了(PS:以前做过web 开发) ...

  3. 课程上线 -“新手入门 : Windows Phone 8.1 开发”

    经过近1个月的准备和录制,“新手入门 : Windows Phone 8.1 开发”系列课程已经在Microsoft 虚拟学院上线,链接地址为:http://www.microsoftvirtuala ...

  4. SQLite.Net-PCLUSING SQLITE IN WINDOWS 10 UNIVERSAL APPS

    USING SQLITE IN WINDOWS 10 UNIVERSAL APPS 1.下载SQLite VSIX package并安装 http://sqlite.org/download.html ...

  5. 将Win8.1/WP8.1应用迁移到Universal Windows Platform

    在上一篇在VS2015 RC打开CTP中创建的工程,我们介绍了怎么在RC中打开CTP中创建的Universal 工程,这一篇我们来讲下怎么将Windows 8.1/WP8.1的应用迁移到Univers ...

  6. 使用 Portable Class Library(可移植类库)开发 Universal Windows App

    今天在这里跟大家聊聊关于 Windows Universal 应用夸平台的问题,首先Universal Windows App的定义相信大家已经有所了解了(如果你是一个刚刚接触 Universal A ...

  7. 如何使用 App Studio 快速定制你自己的 Universal Windows App

    之前我为大家介绍过 App Studio 这只神器可以帮助大家快速制作一个 Windows Phone 8 的应用,今天之所以在写一篇关于 App Studio 的文章是因为,App Studio 经 ...

  8. 使用 .NET 平台,如何玩转 Universal Windows 应用?

    2015年7月30日 本文作者是 Managed Languages 团队项目经理 Lucian Wischik. 不久前,Visual Studio 2015上新增 Windows 10 应用的开发 ...

  9. 怎样使用 App Studio 高速定制你自己的 Universal Windows App

    今天之所以在写一篇关于 App Studio 的文章是由于,App Studio 经过了几次升级功能得到了明显提升还能够调用系统功能了.而且能够更方便的和应用商店关联公布 Universal Wind ...

随机推荐

  1. struts2学习笔记--上传单个和批量文件示例

    struts2提供了对上传文件的支持,将上传后的文件封装为java.io.File对象,开发者只需要在Action中定义一个File类型的变量,然后直接使用该变量,将它复制到目的目录即可. 单个文件上 ...

  2. linux驱动开发之块设备学习笔记

    我的博客主要用来存放我的学习笔记,如有侵权,请与我练习,我会立刻删除.学习参考:http://www.cnblogs.com/yuanfang/archive/2010/12/24/1916231.h ...

  3. WebGIS中矢量切图的初步研究

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.背景 在GIS领域,金字塔技术一直是一个基础性技术,WMTS规范专 ...

  4. Android 短信监听及用途分析

    监听系统短信这个只能作为一个技术点来研究下,读者可能在工作中可能不会哦涉及到,一般的应用软件也不会有这个需求 但是作为程序员呢,多了解一下也是好的. Android 监听系统短信有什么用? 1.对系统 ...

  5. cookie相关

    参考百度百科: Cookie,有时也用其复数形式Cookies,指某些网站为了辨别用户身份.进行session跟踪而储存在用户本地终端上的数据(通常经过加密).定义于RFC2109和2965都已废弃, ...

  6. C# GZip对字符串压缩和解压

    /// <summary> /// 压缩方法 /// </summary> public static string CompressString(string str) { ...

  7. Windows 10预览版14316开启Bash命令支持

    00x0 前言 4月7日凌晨,微软推送了最新的Windows 10一周年更新预览版14316,其中重要的是原生支持Linux Bash命令行支持. 00x1 问题 如何开启Linux Bash命令行? ...

  8. ActiveX(四) mshtml 命名空间 重要接口简介

    在上一篇随笔 ActiveX(三)ActiveX 调用 Js 中,我们已经可以获得js中window对象的强类型接口.即 mshtml.IHTMLWindow2 ,通过该接口.我们可以调用js函数.那 ...

  9. Composer Player 属性设置

    /// <summary> /// 设置选中名称 /// </summary> /// <param name="name"></para ...

  10. JVM-String比较-字节码分析

    一道String字符串比较问题引发的字节码分析 public class a { public static void main(String[] args)throws Exception{ } p ...