今天给大家提供的是一系列的Windows
Phone 7 开发的文章,包括提供试用版应用程序、返回键、全景视图、项目模板以及页面间的导航等。本节内容是Windows
Phone 7开发之:提供试用版应用程序。
之前曾经写过如何将游戏添加到电话的游戏中心中。今天,我会向你展示为应用程序添加试用内容是多么简单。例如,假设你创建了一个50关的游戏。可能你想让用户能免费体验前5关,但要想玩后面的,他们就需要购买这个游戏。本文就像你展示如何做到。
使用LicenseInformation类
通过向我们的页面中添加Microsoft.Phone.Marketplace程序集和相应的名称空间,就可以访问LicenseInformation类了,它直接与程序的“付费”状态相关。
usingMicrosoft.Phone.Marketplace; |
下一步是真正地使用LicenseInformation类,来创建一个实例:
LicenseInformationli = new LicenseInformation(); |
最后,LicenseInformation有一个非常棒的返回布尔值的方法叫IsTrial(),毫无悬念,它允许我们检测程序是否处于试用状态。你可以很方便地将它用于一个if语句,就像这样:
if(!li.IsTrial()) { //Do something that only paid users can do. } else { //Do something that all users, trial or paid, can do. } |
测试试用模式
不幸的是,没有一种用来在试用和已付款状态间切换的内建机制。不过这处理起来很简单。我使用了在App.xaml.cs文件中相同的if语句。用它来检测你是否在调试,如果是,创建一个被我叫做“trialMode”的IsolatedStorageSetting。
下面是整个App()方法,包括App.xaml.cs文件自动生成的代码。在下面的例子中,我将trialMode设为了TRUE。当你测试“已付费”模式时要将它关闭。
IsolatedStorageSettingssettings = IsolatedStorageSettings.ApplicationSettings; publicApp() { // Global handler for uncaught exceptions. UnhandledException += Application_UnhandledException; settings[ "trialMode"] = false; // Show graphics profiling information while debugging. if(System.Diagnostics.Debugger.IsAttached) { settings[ "trialMode"] = true; // Display the current frame rate counters. Application.Current.Host.Settings.EnableFrameRateCounter = true; // Show the areas of the app that are being redrawn in each frame. //Application.Current.Host.Settings.EnableRedrawRegions = true; // Enable non-production analysis visualization mode, // which shows areas of a page that are being GPU accelerated with a colored overlay. //Application.Current.Host.Settings.EnableCacheVisualization = true; } // Standard Silverlight initialization InitializeComponent(); // Phone-specific initialization InitializePhoneApplication(); } |
回顾一下之前的代码,我需要修改if语句来处理这个新的IsolatedStorageSettings值。这次我包含了整个MainPage.xaml.cs文件,所以结合上下文你可以看到所有的内容。
usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Net; usingSystem.Windows; usingSystem.Windows.Controls; usingSystem.Windows.Documents; usingSystem.Windows.Input; usingSystem.Windows.Media; usingSystem.Windows.Media.Animation; usingSystem.Windows.Shapes; usingMicrosoft.Phone.Controls; usingMicrosoft.Phone.Marketplace; usingSystem.IO.IsolatedStorage; namespaceDay23_UsingTrial { public partial class MainPage: PhoneApplicationPage { LicenseInformationli = new LicenseInformation(); IsolatedStorageSettingssettings = IsolatedStorageSettings.ApplicationSettings; // Constructor publicMainPage() { InitializeComponent(); if(!li.IsTrial()||(bool)settings["trialMode"] == false) { //Do something that only paid users can do. } else if (li.IsTrial() || (bool)settings["trialMode"] == true) { //Do something that all users, trial or paid, can do. } } } } |
这就是所有你需要做的,当然这并不是“最好的”处理这种问题的方法,但对我来说它的确可以工作。
Windows Phone 7 开发之:项目模板
在写这篇文章时,我们需要做一些假设。首先,我假设你懂一些Silverlight的知识。去年我曾经写过一个Silverlight
31日谈的系列文章,所以我建议如果没接触过Silverlight你可以从那儿开始学习。本系列中的所有文章都假设你有Silverlight的基础知识。
其次,我假设你已经安装了所有所需的工具。你可以在这里http://developer.windowsphone.com找到并下载它们。你需要Visual
Studio 2010 for Windows Phone和Expression Blend 4 for
Windows Phone。这两个你一定会用到,同时它们完全免费。如果你已经有了这些软件的正式版,它们将会更新这些项目的模板而非在你的机器上添加新的软件。
今天,我们来看看在启动Visual Studio 2010时自带的一个默认的Windows
Phone项目模板:Windows Phone Application。
Solution Explorer(解决方案管理器)
来看一下默认项目的解决方案管理器。我不准备解释每个文件的所有内容,但我会介绍它们的作用。如果你想看这些内容,安装这些工具来试试!非常简单!
ApplicationIcon.png
用来代表你程序的图片,你可以用另外的一个来替换这个图片。用户会在他们的程序中将看到此图片。它很重要,一定要设计好。
App.xaml
这个文件和ASP.NET中的web.config文件很相似。你可以将供整个应用程序使用的数据和设置保存在此处。我也很喜欢将我的样式数据放在此文件中,但这并不是必须的。
App.xaml.cs
上面那个文件的“代码后置”文件,在这儿你可以处理程序的“墓碑”。我们会在第14天中讲解多任务和墓碑的概念。
AppManifest.xml
生成应用程序安装包(XAP)所需的一个简单的应用程序清单文件。
AssemblyInfo.cs
另一个配置文件,它包含了名称和版本的元数据,会被嵌入到生成的程序集文件中。
Background.png
当你的程序被显示到开始界面中就会显示这个图像。它应该和ApplicationIcon.png一样被精雕细琢。
MainPage.xaml
你的首个程序页面。几乎在每个项目中,它都不应该成为唯一的页面。电话还可以处理页面间的前后导航,所以你不应该将所有的功能都堆积到一个XAML页面中。把它们分开,以后你会感谢我的。我们会在明天的文章中深度探索页面间导航。
MainPage.xaml.cs
主页面的“代码后置”文件。当你需要在代码中控制一些行为时,通常在这里进行。与XAML文件中的对象进行交互几乎是必不可少的。在这个系列的文章中会涵盖大量的有关在这个文件(或其他的XAML代码后置文件)中写代码的话题。
SplashScreenImage.jpg
如果你的应用程序需要花费较长时间来载入时会默认显示此图片。你可以自己选择来替换掉这个图片,但记住这仅仅是让用户知晓他们在等待真正的应用程序载入。
WMAppManifest.xml
另一个包含了应用程序特定数据的元数据文件,包括标题,图标位置,功能等等。
Windows Phone 7 开发之:页面间导航
这里我们来探讨如何在Silverlight for Windows Phone中进行页面间导航。这非常重要,原因有二:首先,你不会愿意在一个XAML文件中构建整个应用程序。第二,因为下面的原则,你的程序会自动利用手机内建的返回按键。这允许你的用户想返回到之前的操作时可以向前导航。明天我们来深入讨论返回按键。
在页面间导航有很多种方法,但是我打算只讲一种。我更喜欢叫它简单Web导航。正如其名,这里采取的方式正如你在HTML页面中导航相似。当然还有一些其他的框架可用(像MVVM),但是本篇文章的目的是讲解这个简单的方法。
简单Web导航
假设我们有很多页面,并且我们想给用户能在它们之间穿梭的一种方式。先来构建一个简单的导航UI让我们能做以上的事情,现在开始:
1)创建一个新的Windows Phone Application。
2)添加几个Windows Phone纵向页面。
我们将在今后的文章中讨论页面方向(纵向和横向)。现在只谈纵向。我创建了3个纵向页面:Pasta.xaml,
Sauce.xaml和Cheese.xaml。我将用几种不同的方法把它们联系在一起。
3)改变页面的标题,以便在页面变更后可以知道所在的位置。
当你创建一个新页面时,有一个叫“PageTitle”的XAML元素它默认被设置为“page
name”。在每个页面中都更改这个元素以便于知道你当前处于哪个页面。我喜欢这样做是因为可以减少出错的几率。你会发现当你投入精力制作一个项目时起初的代码看起来都很相似,所以让他们看起来有所区别(至少在编码时)会有很大帮助。
4)在MainPage.xaml中创建几个超链接(hyperlink)。
在页面间建立链接,有几种不同的方式。第一种是全XAML解决方案。为此,我们可以使用超链接按钮(HyperlinkButton)控件。以下是代码:
<HyperlinkButton Content="Pasta" NavigateUri="/Pasta.xaml" Height="30"
HorizontalAlignment="Left" Margin="10,10,0,0" Name="hyperlinkButton1" VerticalAlignment="Top" Width="200" /> <HyperlinkButton Content="Sauce" NavigateUri="/Sauce.xaml" Height="30" HorizontalAlignment="Left" Margin="10,10,0,0" Name="hyperlinkButton2" VerticalAlignment="Top" Width="200" /> <HyperlinkButton Content="Cheese" NavigateUri="/Cheese.xaml" Height="30" HorizontalAlignment="Left" Margin="10,10,0,0" Name="hyperlinkButton3" VerticalAlignment="Top" Width="200" /> |
当你运行项目时,你可以点击任何一个超链接按钮然后跳转到相应的页面中。使用返回键同样可以使你回到上一个界面。如果你返回多次,你会发现一旦越过了程序的第一页你就离开了当前的应用程序。
5)通过代码导航到页面。
如果你喜欢通过代码而非完全使用XAML,你可以仅仅用一些XAML元素来实现。在本例中,我们使用按钮。我创建了3个按钮,每一个都指向相同的事件处理程序。在下面的C#代码中,你会看到我实际上检测了是哪个按钮被点击了,然后导航到相应的页面。返回键的所有功能仍然可用。
XAML
<Button x:Name="PastaButton" Content="Pasta" Click="Button_Click" Width="200" Height="75" /> <Button x:Name="SauceButton" Content="Sauce" Click="Button_Click" Width="200" Height="75" /> <Button x:Name="CheeseButton" Content="Cheese" Click="Button_Click" Width="200" Height="75" /> |
C#
private void Button_Click(object sender, RoutedEventArgs e)
{
Button clickedButton
= sender as Button;
switch (clickedButton.Name)
{
case "PastaButton":
NavigationService.Navigate(
new Uri("/Pasta.xaml", UriKind.Relative));
break;
case "SauceButton":
NavigationService.Navigate(
new Uri("/Sauce.xaml", UriKind.Relative));
break;
case "CheeseButton":
NavigationService.Navigate(
new Uri("/Cheese.xaml", UriKind.Relative));
break;
}
} |
正如你看到的,仅仅使用了NavigationService就将用户的动作记录了下来,同时使用返回键就可以使它沿着决策树返回。
Windows Phone 7 开发之:返回键
之前的文章中,我们讨论了页面导航,以及如何简单的调用NavigationService从而到达程序中的不同页面。简要地提到了返回键,但返回键的复杂性是值得在本系列中单独成文的,主要是因为你可以重写(override)返回键的行为。
返回键如何工作
和浏览器中的返回按钮很相似。你可以点击它通过会话的决策信息后退。它能让你跨越多个站点,还有这些站点中的每个页面。Windows
Phone中的返回键工作方式与之相同。它能让你回到之前访问过的页面,甚至是跨应用程序!
例如,如果我:
打开人物中心(People Hub)。
在联系人列表中选择“Jeff Blankenburg”。
点击他的家庭地址(使我们进入地图应用程序)。
点击开始按钮。
开始游戏。
当点击返回键时,会沿着发生的事件列表后退。
重写返回键行为
是的,你没看错。你可以如你所想重定义返回键的行为。但这不表明允许你通过这种能力做一些不负责任的行为。在任何你想重写返回键行为的时候,你应该确认你所认为的“返回”的意思和你的用户所想的是一样。
例如,你打开了一个弹出框,用户的肌肉记忆可能会使他们按下返回键来关闭弹出框。在这种情况下,他们的本意不是离开应用程序,“返回”仅仅意味着摆脱弹出的对话框。
另一个例子,如果你有个游戏依赖于计时器或实时动作,使用返回键来暂停游戏就比较合适而非让人立即离开。下面是一些此类事件的指导原则:
你应该设身处地为用户考虑那一时刻“返回”对他们意味着什么。
如果再次用户按下返回键,你应该让默认行为执行。
使用返回键暂停游戏是个非常好的想法,但再按一次意味着他们真的想返回到前面,那就得让他们能后退。
这是在Windows Phone中重写返回键的代码:
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e) { //你自己的代码。认真负责些。 e.Cancel = true; //取消默认行为。 } |
后面的文章中,我们讨论设备的方向以及如何在程序中处理横纵方向问题。
Windows Phone 7开发 之:设备方向
前一篇文章我们讨论了Windows Phone的一个专用硬件按钮——返回键.本篇我们聚焦另一个硬件特性:设备方向。
纵向和横向
这两个术语区别并不太明显,纵向是设备的垂直方向,横向是水平方向。这两种方向在Windows
Phone 7中都支持,但默认情况下,Silverlight程序以纵向开始,XNA程序以横向开始(游戏通常在宽屏下表现会更好)。本篇文章中,我们只讨论Silverlight程序,以及方向改变后如何去做,因为在用户使用程序时方向的变化是不可避免的。
默认项目是“只支持纵向的”
如果你看一下MainPage.xaml文件的头部信息,会发现两个属性:
SupportedOrientations="Portrait" Orientation="Portrait" |
可以将SupportedOrientations想象成你准备在程序中支持的可能发生的情况的列表。你可以将SupportedOrientations设置成以下3个值中的任意一个:
Portrait (默认值) Landscape PortraitOrLandscape |
Orientation属性是想让你的程序在启动时以何种方式呈现。它有更多的值可选,但记住如果想要以横向模式启动,你需要将横向包含到SupportedOrientations中。下面是Orientation值的列表:
Landscape LandscapeLeft (将电话向左翻转) LandscapeRight (将电话向右翻转) Portrait PortraitDown (正常的竖直方向) PortraitUp (倒置) |
你可以看到在上表中不仅可以指定纵向或横向,还可以指定这些方向的排列方式。这允许你用你喜欢的方向开始你的应用程序。
改变方向
有两种方式可以改变设备的方向。第一将SupportedOrientation设置为“PortraitOrLandscape”让操作系统为你实现。在大多数情况下,并不推荐这样做,因为你的应用程序界面可能不再适应屏幕了。第二种方式是通过代码实现。我们来看一个例子。
这个简单的界面占据了整个竖直方向的屏幕。
你可以看到在横向时,很多按钮不在屏幕之中。这不是理想的用户体验。简单解决方法是去掉标题。我确信我们的用户可以看出这是一个计算器。我们可以对按钮进行重新布局,如果对于程序来说有意义,那就去做!本篇文章的目的是告诉你如何改变你的程序,而不是告诉你应该改变什么。我用了以下的代码来使标题栏消失和重现(这是MainPage.xaml.cs文件的全部内容):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
namespace Day4_DeviceOrientation
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
this.OrientationChanged += new EventHandler(MainPage_OrientationChanged);
}
void MainPage_OrientationChanged(
object sender, OrientationChangedEventArgs e)
{
if ((e.Orientation == PageOrientation.LandscapeRight)||(e.Orientation == PageOrientation.LandscapeLeft))
{
TitlePanel.Visibility = Visibility.Collapsed;
}
else if ((e.Orientation == PageOrientation.PortraitDown) || (e.Orientation == PageOrientation.PortraitUp))
{
TitlePanel.Visibility = Visibility.Visible;
}
}
}
} |
因为我只关注程序是横向还是纵向(而不是所有的方向),所以同时检测这两个状态并相应地调整界面。你可以将每种情况分开处理使界面看起来不同。
注意我为OrientationChanged事件创建的处理程序。这是一个在方向改变时最简单的识别方法,通常你可以使用将在第11天介绍的加速计。看一下使用新代码后最终的例子:
Windows Phone 7 开发之:全景视图
昨天,我们讨论了独立存储以及如何在程序中将数据保存至设备上。今天,我将完全变换视角,来介绍一个我们可以使用的相对较新的(但十分强大的)控件:全景视图控件。
什么是全景视图控件?
如果你看过Windows Phone 7“HUB”的视频或是截图,全景视图是被广泛运用的。简而言之,它就是选项,导航和数据的多屏幕滚动菜单。下面是一些示例:
好了,现在我们知道全景视图长什么样了,来看看如何实现吧。
创建一个全景视图项目
在这个系列的前15日中,每个项目都是基于默认的Windows Phone
Application模板的。对于全景视图来说,如果你喜欢,可以使用Windows Phone Panorama
Application模板。它在下面的列表中:
然而,很重要的一点是你不是只能使用这个模板来创建一个全景视图。这个项目模板利用了MVVM框架(一种很好的方法),为你预先写好了很多内容。如果想简单一些,全景视图控件是我们可以使用的另一种控件,我们可以将它添加到任意的页面中去。这正是本文想要向你展示的内容。
从工具箱中添加一个全景视图
添加全景视图到你的页面中的第一件事就是它不是可用的默认控件(这就是它没有显示在你的Visual
Studio 2010工具箱中的原因)。在使用之前你必须在页面中添加特定的名称空间。简单的做法是将它添加到工具箱中,然后从中重用它。
首先打开你的工具箱,右击“Windows Phone controls”标签。从列表中选择“Choose
Items…”。
在出现的对话框中,它自动载入并为你打开Windows Phone Components标签。你会看到有很多已经被勾选的控件,这些就是当前在你工具箱中的。向下滚动直到找到Panorama,并添加它(明天我们会讲解枢轴控件,所以你也可以将它一并添加进来)。
一旦你在工具箱中添加了这些,你就可以很简单地在页面中加入全景视图控件了。
在页面中添加全景视图
做完前面的步骤会让你在后面更加轻松。删除掉页面中的所有XAML元素,然后添加你的全景视图。通过从工具箱中拖拽一个全景视图控件,一切就都被设置好了。默认的语法看起来如下:
哈,开始时的内容不多。你还应该注意,在页面中添加一个新的XML名称空间:
xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls" |
既然我们在页面中使用了最少量的代码,让我们来看看现在这个全景视图控件长什么样。下图展示了全景视图控件每个不同部分的样子:
设置全景视图的背景和标题
全景视图控件最酷的一个特色就是可以用一张很大的图片当做背景,它比其余的内容滚动的要慢。找一张绚丽的,有代表性的图片用在程序中。这是我的图片(我的应用程序是用于你在饭馆等吃的时消磨时间的。哦,这是在bowling
Green的Corner Grill餐馆):
想将它用于全景视图控件的背景,我需要将图片添加到项目中,然后创建一个ImageBrush,用此图作为源。你会注意到我将图片的透明度设为了50%。这是因为白色文字在这种亮图上显示的效果不太好。
<controls:Panorama Title="waiter"> <controls:Panorama.Background> <ImageBrush ImageSource="PanoramaBackground.jpg" Opacity=".5" /> </controls:Panorama.Background> </controls:Panorama> |
在电话上看起来像这样:
好了,现在有背景图了。让我们来添加一些内容吧。
创建PanoramaItem(全景视图的项)
现在,我们的程序还不能很好的工作。它仅仅显示了背景图片,还不能滚动,或者显示任何东西。通过添加PanoramaItem,我们可以创建全景视图中独立的项,在这些PanoramaItem中,我们可以添加XAML来显示这些项。
每个PanoramaItem是完全独立于另一个的,所以你可以从技术上让每个项完全不同。我会向你展示PanoramaItem的代码,并且我们会在下一节讨论自定义内容。你会在下面注意到我定义了3个PanoramaItem,并为每一个都设置了标题。这样在截图中可以更好地显示,所以我在代码中包含了它们。
<controls:Panorama Title="waiter"> <controls:Panorama.Background> <ImageBrush ImageSource="PanoramaBackground.jpg" Opacity=".5" /> </controls:Panorama.Background> <controls:PanoramaItem Header="learn"> </controls:PanoramaItem> <controls:PanoramaItem Header="play"> </controls:PanoramaItem> <controls:PanoramaItem Header="all"> </controls:PanoramaItem> </controls:Panorama> |
注意背景和标题是如何滚动的,但实际上它们并不是同一速度的。这样当用户用手划过时程序可以为用户提供非常好的视觉深度。但它现在还是空的。让我们添加一些内容,使它看起来像这样:
向PanoramaItem中添加内容
你完全可以不用,但我还是建议你以ListBox开始。如果有很多内容的话它能让这些内容垂直滚动。说到布局你可以有很多很多选项,但一个ListBox可能会给你带来最大的便利。(另外,在代码中绑定一个列表的数据项是一种很简单的方法。参见来自Scott
Guthrie的教程)
<controls:PanoramaItem Header="play"> <ListBox Margin="0,0,-12,0"> <StackPanel Orientation="Horizontal" Margin="0,0,0,17"> <Image Height="100" Width="100" Source="icons/tictactoe.png" Margin="12,0,9,0"/> <StackPanel Width="311"> <TextBlock Text="tic tac toe" TextWrapping="Wrap"
Style="{StaticResource PhoneTextExtraLargeStyle}"/> <TextBlock Text="the classic two player game" TextWrapping="Wrap"
Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/> </StackPanel> </StackPanel> <StackPanel Orientation="Horizontal" Margin="0,0,0,17"> <Image Height="100" Width="100" Source="icons/numbers.png" Margin="12,0,9,0"/> <StackPanel Width="311"> <TextBlock Text="numbers" TextWrapping="Wrap"
Style="{StaticResource PhoneTextExtraLargeStyle}"/> <TextBlock Text="learn your digits from 1 - 20"
TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/> </StackPanel> </StackPanel> <StackPanel Orientation="Horizontal" Margin="0,0,0,17"> <Image Height="100" Width="100" Source="icons/wordsearch.png" Margin="12,0,9,0"/> <StackPanel Width="311"> <TextBlock Text="word search" TextWrapping="Wrap"
Style="{StaticResource PhoneTextExtraLargeStyle}"/> <TextBlock Text="find as many words as you can"
TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/> </StackPanel> </StackPanel> <StackPanel Orientation="Horizontal" Margin="0,0,0,17"> <Image Height="100" Width="100" Source="icons/animals.png" Margin="12,0,9,0"/> <StackPanel Width="311"> <TextBlock Text="animals" TextWrapping="Wrap"
Style="{StaticResource PhoneTextExtraLargeStyle}"/> <TextBlock Text="hear and learn your favorites"
TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/> </StackPanel> </StackPanel> <StackPanel Orientation="Horizontal" Margin="0,0,0,17"> <Image Height="100" Width="100" Source="icons/alphabet.png" Margin="12,0,9,0"/> <StackPanel Width="311"> <TextBlock Text="alphabet" TextWrapping="Wrap"
Style="{StaticResource PhoneTextExtraLargeStyle}"/> <TextBlock Text="learn your letters" TextWrapping="Wrap"
Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/> </StackPanel> </StackPanel> </ListBox> </controls:PanoramaItem> |
我的这个例子,提供了5个你可以从这个屏幕中启动的应用程序。我创建了一些自定义XAML,并放到了ListBox中。下面是XAML代码,以及模拟器中“Play”这个项的截图:
好了,就这些!这里的每个图标都链接到它们自己的独立XAML文件,但这个全景视图为用户提供了在实际玩儿任何游戏之前都能从我的应用程序导航的能力。
|