解讀Windows Phone開發的六個關鍵模塊
今天給大家提供的是一系列的Windows Phone 7 開發的文章,包括提供試用版應用程序、返回鍵、全景視圖、項目模板以及頁面間的導航等。本節內容是Windows Phone 7開發之:提供試用版應用程序。
之前曾經寫過如何將游戲添加到電話的游戲中心中。今天,我會向你展示為應用程序添加試用內容是多么簡單。例如,假設你創建了一個50關的游戲。可能你想讓用戶能免費體驗前5關,但要想玩后面的,他們就需要購買這個游戲。本文就像你展示如何做到。
使用LicenseInformation類
通過向我們的頁面中添加Microsoft.Phone.Marketplace程序集和相應的名稱空間,就可以訪問LicenseInformation類了,它直接與程序的“付費”狀態相關。
usingMicrosoft.Phone.Marketplace;
下一步是真正地使用LicenseInformation類,來創建一個實例:
LicenseInformationli = new LicenseInformation();
最后,LicenseInformation有一個非常棒的返回布爾值的方法叫IsTrial(),毫無懸念,它允許我們檢測程序是否處于試用狀態。你可以很方便地將它用于一個if語句,就像這樣:
{
//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。當你測試“已付費”模式時要將它關閉。
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.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="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="SauceButton" Content="Sauce" Click="Button_Click" Width="200" Height="75" />
<Button x:Name="CheeseButton" Content="Cheese" Click="Button_Click" Width="200" Height="75" />
C#
{
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中重寫返回鍵的代碼:
{
//你自己的代碼。認真負責些。
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.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<OrientationChangedEventArgs>(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.Background>
<ImageBrush ImageSource="PanoramaBackground.jpg" Opacity=".5" />
</controls:Panorama.Background>
</controls:Panorama>
在電話上看起來像這樣:
好了,現在有背景圖了。讓我們來添加一些內容吧。
創建PanoramaItem(全景視圖的項)
現在,我們的程序還不能很好的工作。它僅僅顯示了背景圖片,還不能滾動,或者顯示任何東西。通過添加PanoramaItem,我們可以創建全景視圖中獨立的項,在這些PanoramaItem中,我們可以添加XAML來顯示這些項。
每個PanoramaItem是完全獨立于另一個的,所以你可以從技術上讓每個項完全不同。我會向你展示PanoramaItem的代碼,并且我們會在下一節討論自定義內容。你會在下面注意到我定義了3個PanoramaItem,并為每一個都設置了標題。這樣在截圖中可以更好地顯示,所以我在代碼中包含了它們。
<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的教程)
<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文件,但這個全景視圖為用戶提供了在實際玩兒任何游戲之前都能從我的應用程序導航的能力。