[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对话框. ...
随机推荐
- Android OkHttp完全解析 --zz
参考文章 https://github.com/square/okhttp http://square.github.io/okhttp/ 泡网OkHttp使用教程 Android OkHttp完全解 ...
- RAC的QA
RAC: Frequently Asked Questions [ID 220970.1] 修改时间 13-JAN-2011 类型 FAQ 状态 PUBLISHED Appli ...
- 搭建Mantis 缺陷管理系统(转)
转自 什么是Mantis MantisBT is a free popular web-based bugtracking system (feature list). It is written i ...
- dwz的form表单中url的变量替换
form表单中action的地址格式 “__URL__/edit/{xxx}”,大括号内的 “xxx” 就是变量名,主要功能是结合table组件一起使用. 下图中的删除.编辑.修改密码都是用了url变 ...
- ios调用系统导航
#import "ViewController.h" #import <MapKit/MapKit.h> @interface ViewController () @p ...
- Javascript 学习之路:鼠标长按事件
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- 汇编学习(二)——8086CPU
一.8086CPU 1.微处理器 (1)微控制机:也称单片机 (2)DSP芯片:数字信号处理芯片 (3)嵌入式微处理器 (4)通用微处理器:PC站.工作站.服务器使用的处理器 2.内部结构: (1)总 ...
- input上下居中问题
IE:不管该行有没有文字,光标高度与font-size一致.FF:该行有文字时,光标高度与font-size一致.该行无文字时,光标高度与input的height一致.Chrome:该行无文字时,光标 ...
- Hbase系统架构
HBase 系统架构 HBase是Apache Hadoop的数据库,能够对大型数据提供随机.实时的读写访问.HBase的目标是存储并处理大型的数据.HBase是一个开源的,分布式的,多版本的,面向列 ...
- Liferay 6.2 改造系列之二十四:修改liferay密码的加密方式
为了便于后期与Cas集成过程中使用数据库用户的方便,将liferay密码的加密方式改为SHA. 在/portal-master/portal-impl/src/portal.properties配置文 ...