原教程地址:http://msdn.microsoft.com/zh-cn/library/windows/apps/xaml/hh986965.aspx
完整项目源码下载:http://download.csdn.net/detail/wxg694175346/5170613
此教程指导你如何结合使用可扩展应用程序标记语言 (XAML) 和 Microsoft Visual Basic 或 C# 创建简单的“Hello, world”Windows 应用商店应用。这是一系列教程中的第一个教程,将为你介绍构建 Windows 应用商店应用时所需了解的内容。
在本教程中,你将了解如何:
我们介绍如何使用 XAML 和 Visual Basic 或 C# 创建 Windows 应用商店应用。
会出现 Visual Studio Express 2012 for Windows 8 开始屏幕。
(接下来,我们将用 "Visual Studio" 指代 Visual Studio Express 2012 for Windows 8。)
会出现“新建项目”对话框。可以在对话框的左侧窗格中选择要显示模板的类型。
在左侧窗格中,展开“已安装”>“模板”,然后展开“Visual Basic”或“Visual C#”并选择“Windows 应用商店”模板类型。对话框的中心窗格会显示一系列用于 Windows 应用商店应用的项目模板。
“空白应用”模板会创建一个最基本的 Windows 应用商店应用,该应用可以编译和运行,但不包含任何用户界面控件或数据。下面的教程将指导你向应用添加控件和数据。
Visual Studio 创建项目并在“解决方案资源管理器”中显示该项目。
尽管“空白应用”为最基本的模板,但该模板仍包含很多文件:
这些文件是使用 Visual Basic 或 C# 的所有 Windows 应用商店应用必不可少的文件。在 Visual Studio 中创建的所有项目都包含这些文件。
“空白应用”项目模板中的 MainPage 基于“空白页”模板。该模板包含实例化 Page 的最少数量的 XAML 和代码。但是,当你为 Windows 应用商店创建应用时,你必须执行更多操作。例如,即便仅仅一页的应用也必须适应多种布局和视图,当挂起时保存其状态,当恢复时还原其状态。Visual Studio 中的其他项目和 Page 模板包含一些其他代码和帮助程序类,这些内容有助于你管理视图和状态。使用“空白应用”项目模板时,通常可以使用其他 Page 模板之一替换空白 MainPage 来利用它们提供的布局和帮助程序类。
在本例中,将默认 MainPage 替换为使用“基本页”模板的页面。此系列的后面教程取决于此模板用于视图和状态管理的帮助程序类。有关可以在 Visual Studio 中选择的 Page 模板的详细信息,请参阅 C#、VB 以及 C++ 项模板。
在空白应用中替换 MainPage 的步骤
要点 如果保留默认名称 "BasicPage1",则该项目将不会正确构建。
首次向“空白应用”模板添加新页面(“空白页”除外)时,Visual Studio 会显示含有消息的对话框,告知你添加操作取决于项目缺失的文件。单击“是”可添加这些文件。将用于多种实用工具类的文件添加到 Common 文件夹中的项目中。
你的页面的 XAML 和代码隐藏文件即被添加到项目中。
要点 新页面会显示设计器中的错误,直至你构建该设计器依赖的帮助程序类。
此时,你创建了一个非常简单的应用。如果你想看它的外观,按 F5 可在调试模式下构建、部署并启动应用。首先会出现默认的初始屏幕。初始屏幕由一个图像 (splashscreen.png) 和背景色(在应用的清单文件中指定)定义。 此处恕不对其进行介绍,但自定义初始屏幕的操作十分简单。(有关具体操作,请参阅添加初始屏幕。)
初始屏幕会消失,然后会出现你的应用。它包含黑屏和标题“我的应用程序”""。
没有关闭应用的按钮或命令。你可以使用关闭手势或 Alt+F4 来关闭应用,但通常不会关闭 Windows 应用商店应用,正如我们在第 2 部分:管理应用生命周期和状态中的详细介绍。按 Windows 键可转到开始屏幕;请注意,部署应用时会将应用的磁贴添加到开始屏幕的最后一组。若要再次运行应用,请在开始屏幕上点击或单击应用的磁贴,或在 Visual Studio 中按 F5 在调试模式下运行该应用。
该过程不会执行很多操作——,只是祝贺你已构建第一个 Windows 应用商店应用!
若要停止调试应用,请按 Alt+Tab 来返回到 Visual Studio。在 Visual Studio 中,单击“调试”>“停止调试”可关闭应用。当你在调试过程中时,无法在 Visual Studio 中编辑。
有关详细信息,请参阅从 Visual Studio 运行 Windows 应用商店应用。
创建使用“空白应用”模板的新项目时,Visual Studio 会创建含有少数文件的应用。若要查看和编辑文件,请双击“解决方案资源管理器”中的文件。可以像展开文件夹一样展开 XAML 文件来查看其关联的代码文件。默认情况下,XAML 文件在拆分视图中打开,该视图显示设计界面和 XAML 编辑器。
在本教程中,你只使用少量以前列出的文件:App.xaml、App.xaml.cs/.vb、MainPage.xaml 以及 MainPage.xaml.cs/.vb。
App.xaml 为声明在应用中所使用资源的位置。此文件包含 ResourceDictionary,它含有对位于 Common 文件夹中的 StandardStyles.xaml ResourceDictionary 的引用。StandardStyles.xaml 提供了一组默认样式,它们为应用提供 Windows 8 外观。
<Application x:Class="HelloWorld.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:HelloWorld"> <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <!-- Styles that define common aspects of the platform look and feel Required by Visual Studio project and item templates --> <ResourceDictionary Source="Common/StandardStyles.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> </Application>
App.xaml.cs/.vb 为 App.xaml 的代码隐藏文件。代码隐藏是与 XAML 页的部分类结合的代码。XAML 与代码隐藏一同组成完整的类。App.xaml.cs/.vb 为应用的入口点。与所有代码隐藏页面一样,它包含一个调用 InitializeComponent
方法的构造函数。你不必编写 InitializeComponent
方法。该方法由 Visual Studio 生成,其主要作用是初始化在 XAML 文件中声明的元素。App.xaml.cs/.vb 还包含一些处理应用激活和挂起的方法。在第 2 部分:管理应用生命周期和状态中,我们将向这些方法添加一些代码。
using System; using Windows.ApplicationModel; using Windows.ApplicationModel.Activation; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; // The Blank Application template is documented at http://go.microsoft.com/fwlink/?LinkId=234227 namespace HelloWorld { /// <summary> /// Provides application-specific behavior to supplement the default Application class. /// </summary> sealed partial class App : Application { /// <summary> /// Initializes the singleton application object. This is the first line of authored code /// executed, and as such is the logical equivalent of main() or WinMain(). /// </summary> public App() { this.InitializeComponent(); this.Suspending += OnSuspending; } /// <summary> /// Invoked when the application is launched normally by the end user. Other entry points /// will be used when the application is launched to open a specific file, to display /// search results, and so forth. /// </summary> /// <param name="args">Details about the launch request and process.</param> protected override void OnLaunched(LaunchActivatedEventArgs args) { Frame rootFrame = Window.Current.Content as Frame; // Do not repeat app initialization when the Window already has content, // just ensure that the window is active if (rootFrame == null) { // Create a Frame to act as the navigation context and navigate to the first page rootFrame = new Frame(); if (args.PreviousExecutionState == ApplicationExecutionState.Terminated) { //TODO: Load state from previously suspended application } // Place the frame in the current Window Window.Current.Content = rootFrame; } if (rootFrame.Content == null) { // When the navigation stack isn't restored navigate to the first page, // configuring the new page by passing required information as a navigation // parameter if (!rootFrame.Navigate(typeof(MainPage), args.Arguments)) { throw new Exception("Failed to create initial page"); } } // Ensure the current window is active Window.Current.Activate(); } /// <summary> /// Invoked when application execution is being suspended. Application state is saved /// without knowing whether the application will be terminated or resumed with the contents /// of memory still intact. /// </summary> /// <param name="sender">The source of the suspend request.</param> /// <param name="e">Details about the suspend request.</param> private void OnSuspending(object sender, SuspendingEventArgs e) { var deferral = e.SuspendingOperation.GetDeferral(); //TODO: Save application state and stop any background activity deferral.Complete(); } } }
在 MainPage.xaml 文件中,为应用定义 UI。你可以直接使用 XAML 标记添加元素,也可以使用 Visual Studio 提供的设计工具。“基本页面”模板创建一个从 LayoutAwarePage
继承的名为 MainPage
(或者你输入的任何名称)的新类。LayoutAwarePage
类扩展了基本的 Page 类并提供导航方法、状态管理以及视图管理。“基本页面”模板还包含一些简单的内容,如后退按钮和页面标题。
<common:LayoutAwarePage x:Name="pageRoot" x:Class="HelloWorld.MainPage" DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}" IsTabStop="false" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:HelloWorld" xmlns:common="using:HelloWorld.Common" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Page.Resources> <!-- TODO: Delete this line if the key AppName is declared in App.xaml --> <x:String x:Key="AppName">My Application</x:String> </Page.Resources> <!-- This grid acts as a root panel for the page that defines two rows: * Row 0 contains the back button and page title * Row 1 contains the rest of the page layout --> <Grid Style="{StaticResource LayoutRootStyle}"> <Grid.RowDefinitions> <RowDefinition Height="140"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <!-- Back button and page title --> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Button x:Name="backButton" Click="GoBack" IsEnabled="{Binding Frame.CanGoBack, ElementName=pageRoot}" Style="{StaticResource BackButtonStyle}"/> <TextBlock x:Name="pageTitle" Grid.Column="1" Text="{StaticResource AppName}" Style="{StaticResource PageHeaderTextStyle}"/> </Grid> <VisualStateManager.VisualStateGroups> <!-- Visual states reflect the application's view state --> <VisualStateGroup x:Name="ApplicationViewStates"> <VisualState x:Name="FullScreenLandscape"/> <VisualState x:Name="Filled"/> <!-- The entire page respects the narrower 100-pixel margin convention for portrait --> <VisualState x:Name="FullScreenPortrait"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="backButton" Storyboard.TargetProperty="Style"> <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PortraitBackButtonStyle}"/> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <!-- The back button and title have different styles when snapped --> <VisualState x:Name="Snapped"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="backButton" Storyboard.TargetProperty="Style"> <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedBackButtonStyle}"/> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="pageTitle" Storyboard.TargetProperty="Style"> <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedPageHeaderTextStyle}"/> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> </Grid> </common:LayoutAwarePage>
MainPage.xaml.cs/.vb 为 MainPage.xaml 的代码隐藏页面。在此,你添加应用逻辑和事件处理程序。“基本页”模板包含 2 个方法,你可以在其中保存和加载页面状态。
using System; using System.Collections.Generic; using Windows.UI.Xaml.Controls; // The Basic Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234237 namespace HelloWorld { /// <summary> /// A basic page that provides characteristics common to most applications. /// </summary> public sealed partial class MainPage : HelloWorld.Common.LayoutAwarePage { public MainPage() { this.InitializeComponent(); } /// <summary> /// Populates the page with content passed during navigation. Any saved state is also /// provided when recreating a page from a prior session. /// </summary> /// <param name="navigationParameter">The parameter value passed to /// <see cref="Frame.Navigate(Type, Object)"/> when this page was initially requested. /// </param> /// <param name="pageState">A dictionary of state preserved by this page during an earlier /// session. This will be null the first time a page is visited.</param> protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState) { } /// <summary> /// Preserves state associated with this page in case the application is suspended or the /// page is discarded from the navigation cache. Values must conform to the serialization /// requirements of <see cref="SuspensionManager.SessionState"/>. /// </summary> /// <param name="pageState">An empty dictionary to be populated with serializable state.</param> protected override void SaveState(Dictionary<String, Object> pageState) { } } }
现在,让我们来向应用添加一些内容。
修改起始页的步骤
确保名为 pageTitle
的 TextBlock 显示在“属性”面板中。默认情况下,“属性”面板位于解决方案资源管理器面板之下。
“属性”面板包含所选对象的属性和值的列表。每个属性值的旁边有一个属性标记,即你可以单击打开一个属性菜单的小矩形符号。Text 属性标记为绿色,表示该属性已设置为资源。
在“属性”面板的“常用”下,单击 Text 属性的“属性标记”。此时将打开“属性”菜单。
代替直接在文本块中输入应用名称,你更新了文本块的 Text 属性绑定到的字符串资源。像这样使用资源可使文本能够重复使用、易于维护并且易于本地化。在 MainPage.xaml 中,按照如下方式更新 AppName
资源定义的 XAML。
<x:String x:Key="AppName">Hello, world!</x:String>
在根 Grid 中,紧挨着 <VisualStateManager.VisualStateGroups>
标记前,添加此 XAML。它包含带有 TextBlock 的StackPanel,它询问用户名、接受用户名的 TextBox 元素、Button 以及另一 TextBlock 元素。
<StackPanel Grid.Row="1" Margin="120,30,0,0"> <TextBlock Text="What's your name?"/> <StackPanel Orientation="Horizontal" Margin="0,20,0,20"> <TextBox x:Name="nameInput" Width="300" HorizontalAlignment="Left"/> <Button Content="Say "Hello""/> </StackPanel> <TextBlock x:Name="greetingOutput"/> </StackPanel>
我们将在部分 3:导航、布局和视图中谈论有关 XAML 布局的详细信息。
按 F5 以运行应用。它的外观如下所示。
你可以在 TextBox 中键入,但此时,单击 Button 不会有任何作用。在接下来的步骤中,你为按钮的 Click 事件创建事件处理程序,该事件显示了个性化问候。向 MainPage.xaml.cs/.vb 文件添加事件处理程序代码。
XAML 元素可以在出现某些事件时发送消息。这些事件消息为你提供了可以采取一些操作响应事件的机会。将用于响应事件的代码放在事件处理程序方法中。 多个应用中最常见事件之一为用户单击 Button。
我们来为按钮的 Click 事件创建事件处理程序。 事件处理程序会从 nameInput
TextBox 控件获取用户名并使用该用户名向 greetingOutput
TextBlock 输出问候。
你应处理什么事件?由于事件可以运行在各种设备上,请牢记务必设计具有触摸输入的 Windows 应用商店应用。应用还必须可以处理来自鼠标或触笔的输入。幸运的是,诸如 Click 和 DoubleTapped 的事件与设备无关。如果你熟悉 Microsoft .NET 编程,你可能已分离用于鼠标、触控以及触笔输入的事件,如 MouseMove、TouchMove 以及StylusMove。在 Windows 应用商店应用中,这些单独的事件使用单个 PointerMoved 事件替换,该事件同样适用于触摸、鼠标以及触笔输入。
添加事件处理程序的步骤
在 XAML 编辑器中,按照如下方式更新“按钮”Button的 XAML 以声明“单击”Click事件处理程序。
<Button Content="Say "Hello"" Click="Button_Click"/>
nameInput
TextBox 控件检索用户名并使用该控件创建问候。使用 greetingOutput
TextBlock 显示结果。
private void Button_Click(object sender, RoutedEventArgs e) { greetingOutput.Text = "Hello, " + nameInput.Text + "!"; }
轻松自定义应用的外观。默认情况下,应用使用深色样式的资源。系统资源还包含浅色主题。我们来尝试一下并看看它的外观。
切换到浅色主题的步骤
RequestedTheme="Light"
以下是添加了浅色主题的完整 Application 标记。
<Application x:Class="HelloWorld.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:HelloWorld" RequestedTheme="Light">
你应使用哪个主题?你需要的任何一个。对于主要显示图像或视频的应用,我们建议使用深色主题;对于包含大量文本的应用,我们建议使用浅色主题。如果你使用的是自定义配色方案,则请使用最适合应用外观和感觉的主题。
注意 启动应用时,会应用主题。应用正在运行时不能更改主题。
在本教程的前面部分,我们已指出 App.xaml 文件包含对 StandardStyles.xaml ResourceDictionary 的参考:
<ResourceDictionary.MergedDictionaries> <!-- Styles that define common aspects of the platform look and feel Required by Visual Studio project and item templates --> <ResourceDictionary Source="Common/StandardStyles.xaml"/> </ResourceDictionary.MergedDictionaries>
此时,所有文本都非常小,因此很难阅读。你可以轻松将标准样式应用到应用中的元素以使其美观。
设置元素样式的步骤
BasicTextStyle 为在 StandardStyles.xaml ResourceDictionary 中定义的资源。
在 XAML 设计图面中,文本外观会发生更改。在 XAML 编辑器中,TextBlock 的 XAML 会进行更新。
<TextBlock Text="What's your name?" Style="{StaticResource BasicTextStyle}"/>
greetingOutput
TextBlock 元素。 提示 TextBlock 中没有文本,但当你将鼠标指针悬停在 XAML 设计图面上时,蓝色轮廓会显示 TextBlock 的位置,以便你可以选择它。
现在你的 XAML 如下所示。
<StackPanel Grid.Row="1" Margin="120,30,0,0"> <TextBlock Text="What's your name?" Style="{StaticResource BasicTextStyle}"/> <StackPanel Orientation="Horizontal" Margin="0,20,0,20"> <TextBox x:Name="nameInput" Width="300" HorizontalAlignment="Left"/> <Button Content="Say "Hello"" Click="Button_Click"/> </StackPanel> <TextBlock x:Name="greetingOutput" Style="{StaticResource BasicTextStyle}"/> </StackPanel>
若要自定义应用的外观和风格,你可以创建自己的样式。 有关详细信息,请参阅快速入门:设置控件样式。
在这里,你创建新样式并将其应用于 greetingOutput
TextBlock。你将样式放置在 App.xaml 中的 ResourceDictionary中。
使用自己的样式的步骤
greetingOutput
TextBlock。注意 要修改的样式必须已应用于控件。在该示例中,“BasicTextStyle”仍然从上一步中应用,因此,该样式即为你将修改其副本的样式。
<TextBlock x:Name="greetingOutput" Style="{StaticResource BigGreenTextStyle}"/>
注意 在 App.xaml 的 XAML 设计器中,没有显示任何内容。
<Style x:Key="BigGreenTextStyle" TargetType="TextBlock"> <Setter Property="Foreground" Value="Green"/> <Setter Property="FontSize" Value="36"/> <Setter Property="FontFamily" Value="{StaticResource ContentControlThemeFontFamily}"/> <Setter Property="TextTrimming" Value="WordEllipsis"/> <Setter Property="TextWrapping" Value="Wrap"/> <Setter Property="Typography.StylisticSet20" Value="True"/> <Setter Property="Typography.DiscretionaryLigatures" Value="True"/> <Setter Property="Typography.CaseSensitiveForms" Value="True"/> </Style>
恭喜你完成第一个教程!你已经了解如何将内容添加到 Windows 应用商店应用。而且你已经了解如何添加交互性和如何设置应用样式。