原文: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. ArcSDE:C#打开SDE数据库的几种方式总结

    转自原文 ArcSDE:C#打开SDE数据库的几种方式总结 1.通过指定连接属性参数打开数据库 /// <param name="server">数据库服务器名< ...

  2. POJ 2185 Milking Grid KMP循环节周期

    题目来源:id=2185" target="_blank">POJ 2185 Milking Grid 题意:至少要多少大的子矩阵 能够覆盖全图 比如例子 能够用一 ...

  3. Mahout快速入门教程 分类: B10_计算机基础 2015-03-07 16:20 508人阅读 评论(0) 收藏

    Mahout 是一个很强大的数据挖掘工具,是一个分布式机器学习算法的集合,包括:被称为Taste的分布式协同过滤的实现.分类.聚类等.Mahout最大的优点就是基于hadoop实现,把很多以前运行于单 ...

  4. js中json法创建对象(json里面的:相当于js里面的=)

    js中json法创建对象(json里面的:相当于js里面的=) 一.总结 json里面的:相当于js里面的= 4.json创建js对象解决命名冲突:多个人为同一个页面写js的话,命名冲突就有可能发生, ...

  5. HDU 3791 二叉搜索树 (数据结构与算法实验题 10.2 小明) BST

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=3791 中文题不说题意. 建立完二叉搜索树后进行前序遍历或者后序遍历判断是否一样就可以了. 跟这次的作业第 ...

  6. Java 学习(21):Java 实例

    Java 实例 本章节我们将为大家介绍 Java 常用的实例,通过实例学习我们可以更快的掌握 Java 的应用. Java 环境设置实例 //HelloWorld.java 文件 public cla ...

  7. css 翻牌 翻转 3d翻转 特效

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. 【45.65%】【codeforces 560B】Gerald is into Art

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  9. [Angular] Subscribing to router events

    In our root component, one thing we can do is subscribe to Router events, and do something related t ...

  10. 《编程导论(Java)&#183;3.2.4 循环语句》

    本文全然复制<编程导论(Java)·3.2.4 循环语句>的内容.除[]中的说明文字.请阅读和比較其它编程教材. 我知道.假设我是一个刚開始学习的人,<编程导论(Java)>非 ...