XAML实例教程系列 - 标记扩展(Markup Extensions) 六

作为描述性语言,XAML使用对象元素声明和其属性调用实现不同操作。在实际项目开发中XAML为控件属性赋值,经常会遇到设计时属性值处于未知状态,而该属性值只有在应用运行时才能获取到,通过简单的XAML属性赋值语法无法实现用户需求,使用XAML标记扩展(Markup Extensions)可以轻松实现XAML页面属性赋值,资源引用,类型转换等操作。
本篇将详细讲解Windows 8应用开发,XAML的标记扩展基础概念和使用方法。(Windows 8和Silverlight 5具有类似的标记扩展概念,如果你已经具有Silverlight经验,通过本文可以快速掌握标记扩展在WinRT中的使用方法。)
标记扩展(Markup Extensions)基础概念
在.Net Framework中,标记扩展功能来自MarkupExtension抽象类,根据功能的不同,从中派生出子类。在.Net Framwork 4.5中MarkupExtension派生类(MSDN引用)如下:

而在Windows 8应用开发中,常用的XAML标记扩展功能包括:
1. Binding(绑定)标记扩展, 实现在XAML载入时,将数据绑定到XAML对象;
2. StaticResource(静态资源)标记扩展, 实现引用数据字典(ResourceDictionary)中定义的静态资源;
3. TemplateBinding(模板绑定)标记扩展, 实现在XAML页面中,对象模板绑定调用;
4. RelativeSource(绑定关联源)标记扩展,实现对特定数据源绑定;
XAML标记扩展语法格式:
标记扩展(Markup Extensions)实例
例如下面代码,简单演示使用Binding标记扩展:
<TextBox Text=”{Binding Path=UserName}”/>
<TextBox Text="{Binding ElementName=sliderOneTimeDataSource, Path=Value, Mode=OneTime}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="150"/>
以上代码中,第一行通过使用Binding标记扩展的Path属性将UserName绑定到元素对象TextBox的Text依赖属性中,使文本内容在运行时动态显示到客户端。
而第二行代码使用Binding标记扩展中EelementBinding(对象元素绑定)功能,绑定对象sliderOneTimeDataSource.Value到TextBox的Text属性中,使文本内容在滑动条内容改变时,TextBox内容同步改变。

另外一个实例,StaticResource(静态资源)标记扩展,
<ListBox Height="200" ItemsSource="{Binding Source={StaticResource teamsCVS}}">
<ListBox.ItemTemplate>
<DataTemplate>
<Border Background="{Binding Color}" Width="200" CornerRadius="10" HorizontalAlignment="Left">
<TextBlock Text="{Binding Name}" Style="{StaticResource BasicTextStyle}" HorizontalAlignment="Center" FontWeight="Bold"/>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
上面代码中,TextBlock引用静态样式资源,Style="{StaticResource BasicTextStyle}",和Web应用CSS样式文件类似,大量样式代码定义在外部资源文件中,使用标记扩展应用对象元素样式。这样的设计方式,方便开发人员代码设计和维护。
BasicTextStyle代码如下:
<Style x:Key="BasicTextStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="{StaticResource ApplicationForegroundThemeBrush}"/>
<Setter Property="FontSize" Value="{StaticResource ControlContentThemeFontSize}"/>
<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"/>
</Style>
相比较前两种标记扩展,TemplateBinding标记扩展使用具有局限性,必须应用于ControlTemplate中,否则XAML将解析报错。
下面代码,在一个按钮(Button)的ControlTemplate中使用TemplateBinding标记扩展,功能实现将Button.Content内容绑定到TextBlock的Text属性中,从而实现自定义控件样式模板效果。

RelatvieSource标记扩展是较为特殊的一个Markup Extension。 在前面的代码中,我们使用了ElementBinding元素绑定一个对象属性到另外一个对象属性。值得留意的是,ElementBinding元素绑定只有在源对象被命名后才能正常使用。
而对RelativeSource则允许绑定未命名源对象属性到目标对象属性。
<Binding RelativeSource="{RelativeSource Self}" .../>
-或-
<object property="{Binding RelativeSource={RelativeSource Self} ...}" .../>
<Binding RelativeSource="{RelativeSource TemplatedParent}" .../>
-或-
<object property="{Binding RelativeSource={RelativeSource TemplatedParent} ...}" .../>
RelativeSource使用Self模式时, 目标对象将作为源对象绑定到自身。这个模式可以实现同一对象元素不同属性之间的绑定操作。例如:
<TextBox Text="{Binding Path=UserName}" ToolTipService.ToolTip="{Binding Text, RelativeSource={RelativeSource Self}}" />
以上代码,附加属性ToolTipService.ToolTip使用RelativeSource标记扩展绑定控件自身Text属性,作为提示信息显示在客户端。
RelativeSource使用TemplatedParent模式时, 仅在控件模板(ControlTemplate)或者数据模板(DataTemplate)下有效。不同的模板,将返回不同类型的绑定结果。例如,在一个 ListBox数据模板(DataTemplate)中应用RelativeSource的TemplatedParent模式,则会返回 ContentPresenter模板内容到对应数据模板中。TemplatedParent模式可以帮助开发人员轻松绑定模板中的属性值到目标对象属性。例如:
<Style TargetType="local:Calendar">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:Calendar">
<Grid>
<TextBlock Text="{Binding Path=Namer,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}" />
<TextBlock Text="{TemplateBinding Namer}" />
....
</Style>
值得注意的是,在控件模板(ControlTemplate)中使用RelativeSource的TemplatedParent模式,”Binding RelativeSource={RelativeSource TemplatedParent}}“等价于”{TemplateBinding}"标记扩展。
两者不同在于,TemplateBinding仅支持单向(One-Way)绑定,而RelativeSource标记扩展支持双向(Two-Way)绑定,这个功能在创建自定义控件模板时特别有用。
内置标记扩展(Markup Extensions)
在WinRT中, x:null是XAML最基础的标记扩展,其作用是设置一个nullable值到对象属性,可以用于初始化对象属性值。例如:
<object>
<object.property>
<x:Null />
</object.property>
</object>
使用XAML标记扩展功能,可以在应用运行时为对象属性赋值,实现动态更新XAML属性,对于应用实时数据更新提供很大的帮助。
今天就讲到这里,欢迎各位留言讨论。
![]() |
源代码下载(VS2012 RC, Windows8 RP) |
运行效果:

XAML实例教程系列 - 标记扩展(Markup Extensions) 六的更多相关文章
- XAML实例教程系列 - 类型转换器(Type Converter)七
XAML实例教程系列 - 类型转换器(Type Converter) 分类: Windows 8 Silverlight2012-06-25 13:40 961人阅读 评论(0) 收藏 举报 butt ...
- XAML实例教程系列 - 资源(Resources)
Kevin Fan分享开发经验,记录开发点滴 XAML实例教程系列 - 资源(Resources) 2012-08-10 12:47 by jv9, 1386 阅读, 1 评论, 收藏, 编辑 在Wi ...
- XAML实例教程系列 - XAML传递参数到值转换类实例 八
Kevin Fan分享开发经验,记录开发点滴 XAML实例教程系列 - XAML传递参数到值转换类实例 2012-06-28 05:25 by jv9, 508 阅读, 0 评论, 收藏, 编辑 继上 ...
- XAML实例教程系列 - 对象和属性(二)
XAML实例教程系列 - 对象和属性 2012-05-22 14:18 by jv9, 1778 阅读, 6 评论, 收藏, 编辑 在前一篇已经介绍XAML概念:“XAML语言是Extensible ...
- XAML实例教程系列 - 开篇(一)
XAML实例教程系列 - 开篇 2012-05-14 11:47 by jv9, 5588 阅读, 8 评论, 收藏, 编辑 去年,曾答应银光中国论坛的朋友推出一个关于XAML语言实例教程系列,帮助学 ...
- XAML实例教程系列 - 事件(Event) 五
Kevin Fan分享开发经验,记录开发点滴 XAML实例教程系列 - 事件(Event) 2012-06-19 01:36 by jv9, 1727 阅读, 7 评论, 收藏, 编辑 Events, ...
- XAML实例教程系列 - 命名空间(NameSpace) 三
XAML实例教程系列 - 命名空间(NameSpace) 2012-05-28 14:14 by jv9, 2205 阅读, 10 评论, 收藏, 编辑 上一篇曾提及XAML中,每个对象元素的声明是对 ...
- XAML实例教程系列 - 依赖属性和附加属性(四)
XAML实例教程系列 - 依赖属性和附加属性 2012-06-07 13:11 by jv9, 1479 阅读, 5 评论, 收藏, 编辑 微软发布Visual Studio 2012 RC和Wind ...
- Silverlight,Windows 8应用开发实例教程系列汇总
Kevin Fan分享开发经验,记录开发点滴 Silverlight,Windows 8应用开发实例教程系列汇总 2012-06-18 01:05 by jv9, 2145 阅读, 3 评论, 收藏, ...
随机推荐
- [JOYOI] 自然数拆分Lunatic版
题目背景 话说小小鱼看了P1171(自然数拆分)之后感觉异常不爽,于是异常邪恶地将题目加强. 题目描述 输入自然数n,然后将其拆分成由若干数相加的形式,参与加法运算的数可以重复. 输入格式 输入只有一 ...
- mysql崩溃恢复
mysql进程崩溃. 杀掉所有mysql进程,在my.cnf文件中写入innodb_recover_force=1,强制并忽略任何错误启动数据库. 用mysqldump导出所有数据,在新机器上部署好m ...
- 零基础入门学习Python(25)--字典:当索引不好用时
知识点 字典属于映射类型. 列表,元祖,字符串等属于序列类型 创建及访问字典 #创建一个字典 >>> dict1 = {'李宁':'一切皆有可能','耐克':'Just do it' ...
- 零基础入门学习Python(12)--列表:一个打了激素的数组(3)
前言 这节课我们继续谈一下Python列表一些知识 知识点 Python常用操作符 比较操作符 >>> list1 = [123] >>> list2 = [234 ...
- PHP 反射API
出处:http://blog.csdn.net/hguisu/article/details/7357421 PHP5添加了一项新的功能:Reflection.这个功能使得phper可以reverse ...
- JS 去除字符串空格
$.trim()是jQuery提供的函数,用于去掉字符串首尾的空白字符. "abc 123 def".replace(/\s/g, "") 去除所有的空格
- Git和SVN共存的方法
刚工作的时候都是用的cvs和svn,对git不熟悉,随着工作的需要,打分支和版本管理的需要,熟悉起来了git,这一用不可收拾,比svn远远好用,尤其是版本分支管理上,切换分支的方便性,现在这家公司还是 ...
- Codeforces Round #364 (Div. 2),只有A与B
A. Cards time limit per test 1 second memory limit per test 256 megabytes input standard input outpu ...
- [BZOJ1029] [JSOI2007]建筑抢修(贪心 + 优先队列)
传送门 把数据存在结构体中,至于怎么贪心? 肯定会有些想法,正确错误先不必说,先来试一试. 1.按照 t2 为第一关键字从小到大排,按照 t1 为第二关键字从小到大排 这个显然错,比如后面有个数的 t ...
- android framework navigationbar自定义
需要实现的目标:在navigationbar上显示录像预览,并且点击按钮可以显示/隐藏NavigationBar 参考文章: http://blog.csdn.net/yanlai20/article ...
