MarkupExtension的使用
Posted lonelyxmas
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MarkupExtension的使用相关的知识,希望对你有一定的参考价值。
原文:MarkupExtension的使用记得第一次看到MarkupExtension是在几年前的一次面试中。很不好意思说,当时不知道是什么东东。最近在项目中又用到了WPF的这个功能,决定在博客里记录一下。
在Xaml中为某个对象以Attribute的方式设置对象的属性时,attribute的值默认只能是字符串。例如:
<TextBlock Text="Text"/>
上面为Text属性设置值"Text"。如果属性的类型为String(如上面代码中的Text属性),这是没有问题的。但是如果属性的类型不是String,比如Foreground属性,它的类型是Brush。我们发现Xaml中仍然是可以通过设置一个字符串来完属性赋值的。例如:
<TextBlock Foreground="Aqua" Text="Foreground"/>
这是因为BCL为Brush类型定义了一个TypeConverter: BrushConverter. 它会在运行时将字符串转换成一个Brush结构。如果我们要在Xaml中直接给Foreground属性传递一个Brush对象怎么办呢?这就到了MarkupExtension发挥作用的时候了。它的作用就是扩充了Attribute方式赋值时只能赋给字符串的限制。让在赋值的时候可以执行后台代码从而产生所期望的对象。其实我们经常用的Binding,StaticResource,DynamicResource等都是属于MarkupExtension. 上代码:
先看一下使用MarkupExtension后xaml的效果:
<Window x:Class="WPFSample.Samples.MarkupExtensionSample" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:me="clr-namespace:WPFSample.Samples.MarkupExtensionSamples" Title="MarkupExtensionSample" Height="300" Width="300"> <Grid> <StackPanel> <TextBlock Foreground="Aqua" Text="Foreground"/> <!--Following xaml code set a foreground using markup extension.--> <TextBlock Foreground="{me:BrushGetter TitleBrush}" Text="Foreground from markup extension"/> <TextBlock Foreground="{me:BrushGetter ContentBrush}" Text="Foreground from markup extension"/> </StackPanel> </Grid> </Window>
再看看BrushGetter的定义:
public class BrushGetter : MarkupExtension { private string _brushName; public BrushGetter(string brushName) { //在Xaml中使用该MarkupExtension时传递brushName参数。 _brushName = brushName; } public override object ProvideValue(IServiceProvider serviceProvider) { //当在通过该MarkupExtension在Xaml中给属性赋值时,该方法将被调用。根据条件返回一个合适的对象即可。 //至于参数serviceProvider,一般情况下用不到。暂时不纠结它了。 switch (_brushName) { case "TitleBrush": return Brushes.Black; case "ContentBrush": return Brushes.Blue; default: break; } return null; } }
最后看看最终效果:
其实使用MarkupExtension来赋值时,运行时会在每次赋值时构造一个Markup Extension对象,传递xaml中定义的参数,然后调用ProvideValue方法获取一个值。
以上是关于MarkupExtension的使用的主要内容,如果未能解决你的问题,请参考以下文章
WPF 让普通 CLR 属性支持 XAML 绑定(非依赖属性),这样 MarkupExtension 中定义的属性也能使用绑定了
InverseBoolConverter 像标记扩展一样使用,但不是从 MarkupExtension 派生的。 XLS0505 XAML