[WP8.1UI控件编程]Windows Phone XAML页面的编译
1.1.2 XAML页面的编译
Windows Phone的应用程序项目会通过Visual Studio完成XAML页面的编译,在程序运行时会通过直接链接操作加载和解析XAML,将XAML和过程式代码自动连接起来。如果你不在乎将XAML文件和过程式代码融合,那么只需要把它添加到Visual Studio的Windows Phone项目中来,并用界面中的Build动作来完成编译即可,一般公共的样式资源的XAML文件都是采用这种方式。但是如果要编译一个XAML文件并将它与过程式代码混合,第一步要做的就是为XAML文件的根元素指定一个子类,可以用XAML语言命名空间中的Class关键字来完成,一般Windows Phone的程序页面是采用这种方式,通常在Windows Phone项目新增的XAML文件都会自动地生成一个对应的XAML.CS文件,并且默认地将两个文件关联起来,例如,添加的XAML文件如下:
< Page
x:Class="PhoneApp1.MainPage"
……>
……省略若干代码
</ Page>
与XAML文件关联起来的XAML.CS文件如下:
namespace PhoneApp1
{
public sealed partial class MainPage : Page
{
……省略若干代码
}
}
通常我们把与XAML文件关联的XAML.CS文件叫作代码隐藏文件。如果你引用XAML中的任何一个事件处理程序(通过事件特性,如Button的Click特性),这里就是我们定义这些事件处理程序的地方。类定义中的partial关键字很重要,因为类的实现是分布在多个文件中的。可能你会觉得奇怪,因为在项目里面只看到了MainPage.xaml.cs文件定义了MainPage类,其实MainPage类还在另外一个地方定义了,只是在项目工程里面隐藏了而已。当我们编译完Windows Phone的项目时,你会在项目的obj\Debug文件夹下看到Visual Studio创建的以g.cs为扩展名的文件,对于每一个XAML文件,你会找到对应有一个g.cs文件。例如,如果我们项目中有一个MainPage.xaml文件,你就会在obj\Debug文件夹下找到MainPage.g.cs文件。下面来看一下MainPage.g.cs文件的结构:
using System;
……
namespace PhoneApp1 {
public partial class MainPage : global::Windows.UI.Xaml.Controls.Page {
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Windows.UI.Xaml.Build.Tasks"," 4.0.0.0")]
(global::Windows.UI.Xaml.Controls.Grid LayoutRoot;
……
private bool _contentLoaded;
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
public void InitializeComponent() {
if (_contentLoaded) {
return;
}
_contentLoaded = true;
global::Windows.UI.Xaml.Application.LoadComponent(this, new global::System.Uri("ms-appx:///MainPage.xaml"), global::Windows.UI.Xaml.Controls.Primitives.ComponentResourceLocation.Application);
LayoutRoot = (global::Windows.UI.Xaml.Controls. Grid)this.FindName("LayoutRoot");
……
}
}
}
从MainPage.g.cs文件中我们可以看到,MainPage类在这里还定义了一些控件和相关的方法,并且InitializeComponent()方法里面加载和解析了MainPage.xaml文件MainPage.cs文件里面的MainPage()方面里面调用的InitializeComponent()方法就是在MainPage.g.cs文件里面定义的。在xaml页面中声明的控件,通常会在.g.cs中生成对应控件的内部字段。实际上这取决于控件是否有x:Name属性,只要有这个属性,都会自动调用FindName方法,用于把字段和页面控件关联。没有x:Name属性,则没有字段,这种关联会有一定的性能浪费,因为是在应用载入控件的时候,通过LoadComponents方法关联的,而xaml也是在这个时候动态解析的。
在项目的obj\Debug文件夹下,我们还找到了g.i.cs为扩展名的文件,对于每一个XAML文件,你也会找到对应有一个g.i.cs文件,并且这些g.i.cs文件与对应的g.cs文件是基本一样的。那么这些g.i.cs文件又有怎样的含义呢?其实这些g.i.cs文件并不是在编译的时候生成的,而是当你创建了XAML文件的时候就马上生成,或者你修改了XAML文件g.i.cs文件也会跟着改变,而g.cs文件则是必须要成功编译了项目之后才会生成的。文件后缀中的g表示generated产生的意思,i表示intellisense智能感知的意思,g.i.cs文件是XAML文件对应的智能感知文件,在vs中利用go to definition功能找InitializeComponent方法的实现的时候,进入的就是g.i.cs文件的InitializeComponent方法里面。
1.1.3 动态加载XAML
动态加载XAML是指在程序运行时通过解析XAML格式的字符串或者文件来动态生成UI的效果。通常情况下,Windows Phone的界面元素都是通过直接读取XAML文件的内容来呈现的,如上一小节讲解的那样通过XAML文件和XAML.CS文件关联起来编译,这也是默认的UI实现的方式,但是在某些时候你并不能预先设计好所有的XAML元素,而是需要在程序运行的过程中动态地加载XAML对象,那么这时候就需要使用到动态加载XAML来实现了。
在应用程序里面动态加载XAML需要使用到XamlReader.Load方法来实现,XamlReader 类是为分析 XAML 和创建相应的 Windows Phone 对象树提供 XAML 处理器引擎,XamlReader.Load 方法可以分析格式良好的 XAML 片段并创建相应的 Windows Phone对象树,然后返回该对象树的根。大部分可以再XAML页面上编写的代码,我们都可以通过动态加载XAML的形式来实现,不仅仅是普通的UI控件,动画等其他的XAML代码我们一样可以动态加载,如:
// 一个透明度变化动画的XAML代码的字符串
private const string FadeInStoryboard =
@"<Storyboard xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"">
<DoubleAnimation
Duration=""0:0:0.2""
Storyboard.TargetProperty=""(UIElement.Opacity)""
To=""1""/>
</Storyboard>";
//使用XamlReader.Load方法加载XAML字符串并且解析成动画对象
Storyboard storyboard = XamlReader.Load(FadeInStoryboard) as Storyboard;
使用 XamlReader.Load方法动态加载XAML对XAML的字符串是有一定的要求的,那么这些“格式良好的 XAML 片段”必须要符合以下要求:
(1)XAML 内容字符串必须定义单个根元素,使用XamlReader.Load创建的内容只能赋予一个Windows Phone对象,它们是一对一的关系。
(2)内容字符串 XAML 必须是格式良好的 XML,并且必须是可分析 XAML。
(3)所需的根元素还必须指定某一默认的 XML 命名空间值。这通常是命名空间 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"。
下面给出动态加载XAML的示例: 演示了使用XamlReader.Load方法加载XAML字符串生成一个按钮和加载XAML文件生成一个矩形。
代码清单1-1:动态加载XAML(源代码:第1章\Examples_1_1)
MainPage.xaml文件主要代码
------------------------------------------------------------------------------------------------------------------
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel x:Name="sp_show">
<Button x:Name="bt_addXAML" Content="加载XAML按钮" Click="bt_addXAML_Click"></Button>
</StackPanel>
</Grid>
Rectangle.xaml文件代码:被动态加载到程序里面去的XAML文件
------------------------------------------------------------------------------------------------------------------
<Rectangle xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="200" Width="480">
<Rectangle.Fill>
<LinearGradientBrush>
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="Red" Offset="0.5"/>
<GradientStop Color="Black" Offset="1"/>
</LinearGradientBrush >
</Rectangle.Fill>
</Rectangle>
MainPage.xaml.cs文件主要代码
------------------------------------------------------------------------------------------------------------------
// 加载XAML按钮
private void bt_addXAML_Click(object sender, RoutedEventArgs e)
{
//注意XAML字符串里面的命名空间"http://schemas.microsoft.com/winfx/2006/xaml/presentation" 不能少。
string buttonXAML = "<Button xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' " +
" Content=\"加载XAML文件\" Foreground=\"Red\"></Button>";
Button btnRed = (Button)XamlReader.Load(buttonXAML);
btnRed.Click += btnRed_Click;
sp_show.Children.Add(btnRed);
}
// 已加载的XAML按钮关联的事件
async void btnRed_Click(object sender, RoutedEventArgs e)
{
string xaml = string.Empty;
//加载程序的Rectangle.xaml文件
StorageFile fileRead = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync("Rectangle.xaml");
// 读取文件的内容
xaml = await FileIO.ReadTextAsync(fileRead);
// 加载Rectangle
Rectangle rectangle = (Rectangle)XamlReader.Load(xaml);
sp_show.Children.Add(rectangle);
}

本文来源于《深入理解Windows Phone 8.1 UI控件编程》
源代码下载:http://vdisk.weibo.com/s/zt_pyrfNHoezI
欢迎关注我的微博@WP林政
WP8.1技术交流群:372552293
[WP8.1UI控件编程]Windows Phone XAML页面的编译的更多相关文章
- [WP8.1UI控件编程]Windows Phone大数据量网络图片列表的异步加载和内存优化
11.2.4 大数据量网络图片列表的异步加载和内存优化 虚拟化技术可以让Windows Phone上的大数据量列表不必担心会一次性加载所有的数据,保证了UI的流程性.对于虚拟化的技术,我们不仅仅只是依 ...
- [WP8.1UI控件编程]Windows Phone VirtualizingStackPanel、ItemsStackPanel和ItemsWrapGrid虚拟化排列布局控件
11.2.2 VirtualizingStackPanel.ItemsStackPanel和ItemsWrapGrid虚拟化排列布局控件 VirtualizingStackPanel.ItemsSta ...
- [WP8.1UI控件编程]Windows Phone动画方案的选择
8.1 动画方案的选择 Windows Phone的动画实现方式有线性插值动画(3种类型).关键祯动画(4种类型)和基于帧动画,甚至还有定时器动画,然后动画所改变的UI元素属性可以是普通的UI元素属性 ...
- [WP8.1UI控件编程]Windows Phone理解和运用ItemTemplate、ContentTemplate和DataTemplate
2.2.5 ItemTemplate.ContentTemplate和DataTemplate 在理解ItemTemplate.ContentTemplate和DataTemplate的关系的之前,我 ...
- [WP8.1UI控件编程]Windows Phone自定义布局规则
3.2 自定义布局规则 上一节介绍了Windows Phone的系统布局面板和布局系统的相关原理,那么系统的布局面板并不一定会满足所有的你想要实现的布局规律,如果有一些特殊的布局规律,系统的布局面板是 ...
- [WP8.1UI控件编程]SemanticZoom控件实现分组列表
11.1.5 SemanticZoom实现分组列表 SemanticZoom控件可以让用户实现一种更加高级的列表,这种列表可以对列表的项目进行分组,同时这个SemanticZoom控件会提供两个具有相 ...
- 《深入理解Windows Phone 8.1 UI控件编程》基于最新的Runtime框架
<深入理解Windows Phone 8.1 UI控件编程>本书基于最新的Windows Phone 8.1 Runtime SDK编写,全面深入地论述了最酷的UI编程技术:实现复杂炫酷的 ...
- 如何添加地图控件到Windows Phone 8的页面中
原文 如何添加地图控件到Windows Phone 8的页面中 本主题介绍了各种方法来添加一个地图控件到Windows Phone 8的项目.该地图控件在Windows Phone的SDK 8.0的库 ...
- MFC控件编程之 按钮编辑框.静态文本的使用,以及访问控件的七种方法.
MFC控件编程之 按钮编辑框.静态文本的使用以及访问控件的七种方法. 一丶按钮.静态文本的通用属性. 他们都有一个属性.就是可以输入标题内容.以及可以自定义控件ID. 创建一个MFC Dlg对话框. ...
随机推荐
- probe函数何时调用的
转自:http://blog.csdn.net/xiafeng1113/article/details/8030248 Linux中 probe函数何时调用的 所以的驱动教程上都说:只有设备和驱动的名 ...
- 个推+DCLOUD,推送消息和透传消息
DCLOUD方案中集成了个推方案,最好是用个推来做推送相关的东西 消息分2类: 1.推送消息,这种一般会出现在手机的最上面的通知栏,用户是肯定会知道的 2.透传消息,这种一般就是一个Alert提示框, ...
- Delphi的TThread中的FreeOnTerminate成员
类 Create 了就要 Free; 但 TThread(的子类) 有特殊性, 很多时候我们不能确定新建的线程什么时候执行完(也就是什么时候该释放); 如果线程执行完毕自己知道释放就好了, 所以 ...
- HDU5115 Dire Wolf(区间DP)
渐渐认识到区域赛更侧重的是思维及基本算法的灵活运用,而不是算法的量(仅个人见解),接下来要更多侧重思维训练了. 区间DP,dp[i][j]表示从i到j最终剩余第i 与第j只的最小伤害值,设置0与n+1 ...
- 攻城狮在路上(伍)How tomcat works(四)Tomcat的默认连接器
在第4章中将通过剖析Tomcat4的默认连接器的代码,讨论需要什么来创建一个真实的Tomcat连接器. 注意:本章中提及的“默认连接器”是指Tomcat4的默认连接器.即使默认的连机器已经被 ...
- jq与js 区别
$(this).html(666); <div id="a">123</div> <script> $("#a").clic ...
- POJ 1655 Balancing Act 树的重心
Balancing Act Description Consider a tree T with N (1 <= N <= 20,000) nodes numbered 1...N. ...
- LeetCode——Rotate Image(二维数组顺时针旋转90度)
问题: You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockw ...
- linux下java环境配置
非常简单的三行命令就搞定了! $ sudo add-apt-repository ppa:webupd8team/java$ sudo apt-get update$ sudo apt-get ins ...
- PHP之echo/print
1.PHP中有两个基本的输出方式:echo和print: 2.echo和print的区别: **echo:可以输出一个或多个字符串: **print:只允许输出一个字符串,返回值总为1: 3.echo ...