原文:wpf中xaml的类型转换器与标记扩展

这篇来讲wpf控件属性的类型转换器

类型转换器

类型转换器在asp.net控件中已经有使用过了,由于wpf的界面是可以由xaml组成的,所以标签的便利也需要类型转换器.两者的应用是非常之相似的.

如设置Margin属性
用xaml方式

<Button Margin="1,2,3,4"></Button>

cs代码

Button btn = new Button();
btn.Margin = new Thickness(1, 2, 3, 4);

通过xaml设置Margin会将此属性通过类型转换器转成Thickness类型.关于类型转换器相关知识,这里不多介绍.下面来介绍xaml的标记扩展功能.

标记扩展

标记扩展在wpf的应用中非常之广泛的.如
数据绑定语法 {Binding Path=…}
静态资源引用 {StaticResource …}
指定数据类型{x:Type prefix:typeNameValue}

标记扩展带来很多好处,一般情况下,xaml的属性值都是文本字符串形式通过类型转换器形式转成对象(标签化语言也存在着局限性).标记扩展可以让属性引用某个静态对象的引用,当然这只是其中的一个功能,语法则是以左右大括号以区别({}).

左上右下问题

这里我们来比较类型转换器做不到的问题

我想大家在刚学wpf或者silverlight的时候,在设置Margin属性的时候,都常常会忘掉四边的顺序,即左上右下,如下blend的属性编辑器.

换个思路,你想把Margin的左上右下的顺序变化就不可以了,因为这是类型转换器,这个顺序是定死的.如果用标记扩展的话,我们可以假设有下面的语法
{Margin Top=76,Left=76,Right=168,Bottom=0}
虽然感觉起来比直接写xx,xx,xx,xx这样麻烦,但增加了灵活性.主要问题是标记扩展可以记录属性值,类型转换器只能用文本字符串表示.
一个复杂属性在xaml的表示方法两种方法都可以,标记扩展提供了一个多的选择.看应用而定.当然在没有类型转换器的情况下,xaml也允许这样写法.相对而言就稍微的复杂一些,一切都是为了简化.

<Button>
<Button.Margin>
<Thickness Left="0" Top="0" Right="0" Bottom="0"></Thickness>
</Button.Margin>
</Button>

<Button Margin="{Margin Top=0,Left=0,Right=0,Bottom=0}" />

<Button Margin="0,0,0,0" />

比较上面三种方式,肯定最后一个最简单,对于记忆不好的也可以尝试第二种,其实第标记扩展也需要你记对象的属性,万一大小写出错那也麻烦,第一种嘛,代码量又太多了,要是都设置一个属性都这样,那代码就多了.所以各有各自的好处.

自定义标记扩展

标记扩展本身与设计时没有关系,但类型转换器却是设计时必须的功能,二两者又有着类似之处,所以这里介绍一下.

下面介绍自定义标记扩展的方法

(1)定义一个派生自System.Windows.Markup.MarkupExtension的类,该类要求重写ProvideValue方法

namespace WPF.Controls
{
public class ThicknessExtension : MarkupExtension
{
public override object ProvideValue(IServiceProvider serviceProvider)
{
throw new NotImplementedException();
}
}
}

(2)与xml命名空间关联,在程序集项目中的AssemblyInfo添加元数据,XmlnsDefinition元数据可以帮助统一命名空间,因为这样我们才可以很简单的使用wpf内置控件(很多控件都在不同命名空间下),XmlnsPrefix的作用就如asp.net内置控件以asp开始一样<asp:Label />

[assembly: XmlnsDefinition("http://wpf.controls", "WPF.Controls")]
[assembly: XmlnsPrefix("http://wpf.controls", "ext")]

现在我们将ProvideValue方法变更为

public override object ProvideValue(IServiceProvider serviceProvider)
{
return new Thickness();
}

然后在xaml中使用该扩展标记

<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ext="http://wpf.controls"
Title="Window1" Height="100" Width="200">
<Grid>
<Button Margin="{ext:Thickness}" Content="Hello" />
</Grid>
</Window>

上面代码可以成功运行,我们还需要为扩展标记添加属性,用于传递参数.

(3)添加属性. 在xaml中添加的对象,都以默认的构造函数进来,同时可以用MarkupExtensionReturnType指定标记扩展返回的安全类型

[MarkupExtensionReturnType(typeof(Thickness))]
public class ThicknessExtension : MarkupExtension
{
public override object ProvideValue(IServiceProvider serviceProvider)
{
return new Thickness(Left,Top,Right,Bottom);
} public ThicknessExtension()
{
} public double Bottom { get; set; }
public double Left { get; set; }
public double Right { get; set; }
public double Top { get; set; }
}

现在就可以使用了

<Button x:Name="demo" Margin="{ext:Thickness Left=10,Bottom=10,Right=10,Top=30}"
Content="Hello"> </Button>

wpf中xaml的类型转换器与标记扩展的更多相关文章

  1. [No000012C]WPF(4/7)类型转换器和标记扩展[译]

    介绍 之前讨论了WPF的基础架构,然后逐步开始学习布局面板,转换,介绍了不同的控件,容器,UI转换等.在这篇文章中,我将讨论每个创建XAML应用前的开发人员应该了解的关于XAML最重要的东西. 标记扩 ...

  2. 整理:WPF中Xaml中绑定枚举的写法

    原文:整理:WPF中Xaml中绑定枚举的写法 目的:在Combobox.ListBox中直接绑定枚举对象的方式,比如:直接绑定字体类型.所有颜色等枚举类型非常方便 一.首先用ObjectDataPro ...

  3. WPF中如何选择合适的元数据标记?(英文)

    原文:WPF中如何选择合适的元数据标记?(英文) FrameworkPropertyMetadataOptions Enumeration:Specifies the types of framewo ...

  4. springmvc中如何自定义类型转换器

    package com.hope.utils;import org.springframework.core.convert.converter.Converter;import org.spring ...

  5. WPF中,如何将Vista Aero效果扩展到整个窗口

    原文:WPF中,如何将Vista Aero效果扩展到整个窗口   WPF中,如何将Vista Aero效果扩展到整个窗口                                         ...

  6. WPF中XAML的触发器的属性,事件 都有那些?以及如何寻找

    在编写XAML的触发器时,会有属性,事件. 那么这些都是哪里来的呢? 属性,是附加属性或者依赖属性 事件,那就是事件. 如何寻找呢? 很简单,在想要使用的触发器的对象上(也就是有光标的时候)按下F12 ...

  7. 【随记】WPF中xaml输入中文乱码问题解决

    在Visual Studio中开发WPF应用程序时,在XMAL文档编写界面输入中文时变为乱码.可能的原因之一是VS中安装了VAssistX插件,导致编码冲突,使中文输入乱码.解决方法是在VAssist ...

  8. WPF中Xaml编译正常而Designer Time时出错的解决办法

    开发wpf时我们经常遇到一个xaml文件在设计时显示解析错误(比如在:VS或者Blend)而编译正常运行正常. 原因是:xaml的在Debug版本下必须为anyCPU. 解决办法: 1.打开工程文件x ...

  9. WPF中XAML转义字符

    字符 转义字符 备注 & (ampersand) & 这个没什么特别的,几乎所有的地方都需要使用转义字符 > (greater-than character) > 在属性( ...

随机推荐

  1. swift开发网络篇—NSURLConnection基本使用

    iOS开发网络篇—NSURLConnection基本使用 一.NSURLConnection的常用类 (1)NSURL:请求地址 (2)NSURLRequest:封装一个请求,保存发给服务器的全部数据 ...

  2. (转)ipv4的网段表示方法

    简单一点举例说明:ip段:10.0.0.1-10.0.0.255            的表示方法:10.0.0.0/24ip段:10.0.0.1-10.0.255.255        的表示方法: ...

  3. POJ 1952 BUY LOW, BUY LOWER DP记录数据

    最长递减子序列.加记录有多少个最长递减子序列.然后须要去重. 最麻烦的就是去重了. 主要的思路就是:全面出现反复的值,然后还是同样长度的子序列.这里的DP记录的子序列是以当前值为结尾的时候,而且一定选 ...

  4. ES权威指南1

    Elasticsearch学习笔记 一 本文版权归博客园和作者吴双本人共同所有 转载和爬虫请注明原文地址 www.cnblogs.com/tdws. 本文参考和学习资料 <ES权威指南> ...

  5. [转载]MVC中单用户登录

    转自:http://www.cnblogs.com/firstcsharp/archive/2013/05/19/3087481.html 把下面这段代码放在登录用户验证以后:   //用户登录验证通 ...

  6. Instruments性能优化-Core Animation

    简书地址:http://www.jianshu.com/users/6cb2622d5eac/latest_articles 当App发展到一定的规模.性能优化就成为不可缺少的一点.可是非常多人,又对 ...

  7. 嵌入式linux串口通信自发自收测试程序

     /*串口自收自发程序主函数*/#include"uart_api.h"int main(){ int fd; char buff[BUFFER_SIZE]; char buff2 ...

  8. Cocos2d-x学习笔记(16)(常见22种特效)

    1.CCShaky3D::create(int range.bool shakeZ,const ccGridSize& gridSize,float duration)//创建一个3D晃动的特 ...

  9. [TypeScript] Catch unsafe use of "this" in TypeScript functions

    this is probably the most tricky thing to use in JavaScript and therefore TypeScript. Fortunately th ...

  10. iOS Animation具体解释

    iOS Animation具体解释 本篇仅仅要解说iOS中动画的使用. Animtion主要分为两类:UIView动画和CoreAnimation动画. UIView动画有UIView属性动画,UIV ...