TypeConverter

XAML中的Attribute只接受String类型的值,例如:

  1. <Grid Background="Red"/>

问题来了,XAML解释器是如何将这个"Red"解释为Backgroud可接受类型的?事实上,这里使用了类型转换器(TypeConverter)。所谓类型转换器,顾名思义就是从一种类型转换为另一种类型的手段。简而言之就是将String类型的Red转换成Color类型了。

这里举两个简单示例来阐述如何使用TypeConvert。

示例1:Name转换为Human

先定义一个Human类,包含两个字段 Name 和 Child。

  1. class Human
  2. {
  3. private string name;
  4. private Human child;
  5. public string Name
  6. {
  7. get { return name; }
  8. set { name = value; }
  9. }
  10. public Human Child
  11. {
  12. get { return child; }
  13. set { child = value; }
  14. }
  15. public Human()
  16. {
  17. Name = string.Empty;
  18. Child = null;
  19. }
  20. public Human(string name)
  21. :this ()
  22. {
  23. Name = name;
  24. }
  25. }

然后需要定义TypeConverter这个类。首先有个基本概念得明确,就是类型转换器的Source和Target。对于这个例子,使用String类型作为Source,Human作为Target,当然反过来也没有任何问题。于是就新建一个类型转换器 NameToHumanTypeConverter~

第一点:任何的类型转换器都必须继承于TypeConverter类。

第二点:需要重写方法

  • CanConvertFrom
  • ConvertFrom
  • CanConverTo
  • ConvertTo

注意一个方向的问题,From(String -> Human),To(Human -> String)。可以看到类型转换器是支持双向操作的,这个示例只用到From就足以。

  1. public class NameToHumanTypeConverter : TypeConverter
  2. {
  3. public override bool CanConvertFrom(ITypeDescriptorContext context, System.Type sourceType)
  4. {
  5. if (sourceType == typeof(string))
  6. return true;
  7. else
  8. return base.CanConvertFrom(context, sourceType);
  9. }
  10. public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
  11. {
  12. if (value != null && value is string)
  13. {
  14. Human human = new Human();
  15. human.Name = (string)value;
  16. return human;
  17. }
  18. else
  19. {
  20. return base.ConvertFrom(context, culture, value);
  21. }
  22. }
  23. }

接下来将这个类型转换器以Attribute的形式添加到Human类,添加的目的是为了实现自动转化,第二个示例会说明这个问题。

  1. [TypeConverter(typeof(NameToHumanTypeConverter))]
  2. class Human
  3. {
  4. // ...
  5. }

修改XAML及后台事件代码。

  1. <Window x:Class="类型转换01.MainWindow"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. xmlns:codes="clr-namespace:类型转换01"
  5. Title="MainWindow" Height="350" Width="525">
  6. <Window.Resources>
  7. <codes:Human x:Key="man" Name="Louis" Child="Liu"></codes:Human>
  8. </Window.Resources>
  9. <Grid>
  10. <Button Click="Button_Click"></Button>
  11. </Grid>
  12. </Window>
  1. private void Button_Click(object sender, RoutedEventArgs e)
  2. {
  3. Human human = this.FindResource("man") as Human;
  4. MessageBox.Show(string.Format("Man: {0}\nChild: {1}", human.Name, human.Child.Name));
  5. }

运行程序查看效果:

可以看到成功地将 Louis 和 Liu 转换成了两个Human对象。

示例2:Coordinate转换为String

大部分内容和示例1一致,这个示例仅仅是为了说明给类添加类型转换器的必要性,直接上代码:

若要使用如下的TypeDescriptor.GetConverter这个静态方法,则必须给Coordinate类附加类型转换器这个Attribute。

  1. static void Main(string[] args)
  2. {
  3. CoordinateToStringTypeConverter converter = new CoordinateToStringTypeConverter();
  4. Coordinate testCoordinate = new Coordinate(1.2, 3.4);
  5. string resultString = (string)converter.ConvertFrom(testCoordinate);
  6. Console.WriteLine(resultString);
  7. resultString = (string)TypeDescriptor.GetConverter(typeof(Coordinate)).ConvertFrom(testCoordinate);
  8. Console.WriteLine(resultString);
  9. string testString = "5.6,7.8";
  10. Coordinate resultCoordinate = (Coordinate)converter.ConvertTo(testString, typeof(Coordinate));
  11. Console.WriteLine(resultCoordinate);
  12. resultCoordinate = (Coordinate)TypeDescriptor.GetConverter(typeof(Coordinate)).ConvertTo(testString, typeof(Coordinate));
  13. Console.WriteLine(resultCoordinate);
  14. }

另外在MSDN上看到一段内容,说是Markup Extension的结果不能再作为TypeConverter的Source使用,原文如下:

Markup extensions and type converters fill orthogonal roles in terms of XAML processor behavior and the scenarios that they are applied to. Although context is available for markup extension usages, type conversion behavior of properties where a markup extension provides a value is generally is not checked in the markup extension implementations. In other words, even if a markup extension returns a text string as its ProvideValue output, type conversion behavior on that string as applied to a specific property or property value type is not invoked, Generally, the purpose of a markup extension is to process a string and return an object without any type converter involved.

来自为知笔记(Wiz)

附件列表

时间: 2024-09-29 15:51:01

TypeConverter的相关文章

自定义类型转换器之TypeConverter

C#提供了很多类型转换的方法如ConvertToInt.int.Parse.int.tryParse等等,这些方法都能将一个C#的基本数据类型转换成另一个C#基本数据类型.那么.既然如此,C#肯定会提供某种机制来让我们编写自定义的类型转换器. so.C#提供了一个类型-TypeConverter来帮助我们完成类型转换的功能,TypeConverter类就是将一种类型(object,当然可以是任意类型)转换成一种类型(一般为string,当然也可以是其他的类型).或者将另一种类型转换回来. 1.所

WPF:使用TypeConverter

所谓TypeConverter就是类型转换器,支持两种类型之间相互转换 你可以重写转换逻辑,只要你清楚转换的协议,就可以实现类型互转. 定义一个Person类型,具有一个int类型的Age属性: public class Person { public int Age { get; set; } } 在XAML中添加一个Person的资源: <Window.Resources> <local:Person x:Key="person"></local:Pe

TypeConverter使用

如下代码, <Window.Resources> <local:Human x:Key="human" Name="Tester1" Child="ChildOfTester1"/> </Window.Resources> class Human { public string Name{get;set;} public Human Child{get;set;} } 为了让以上代码工作,则必须提供一个类型转换

自定义控件类型转换器TypeConverter和ExpandableObjectConverter

一.TypeConverter 提供一种将当前属性的类型转换为另一种类型的方法.可通过继承TypeConverter自定义类型转换的格式. 实现自定义类型转换可重写方法: CanConvertFrom.ConvertFrom.CanConvertTo.ConvertTo 二.ExpandableObjectConverter 提供在可扩展对象与其他各种表示形式之间实现转换的类型转换器.

WPF属性与特性的映射(TypeConverter)

1,定义一个类 public class Human { public string Name { get; set; } public Human Child { get; set; } } 2在XAML文件中引用 <Window.Resources> <Local:Human x:Key="human" Child="明洋" x:Name="human"></Local:Human> </Window

关于:TypeConverter 无法从 System.String 转换

TypeConverter 无法从 System.String 转换 处理方法: 1: [DX Support Team: The issue was resolved by its Owner] i have figured out the problem and fixed it. if i set e.KeyExpression at selecting event for LINQDataSource then its okay. in 12.2.8, you had default v

MVC框架中的值提供(一)

在MVC框架中action方法中的Model数据的绑定的来源有很多个,可能是http请求中的get参数或是post提交的表单数据,会是json字符串或是路径中的相关数据;MVC框架中针对这些不同的数据来源抽象了IValueProvider接口; public interface IValueProvider { bool ContainsPrefix(string prefix); ValueProviderResult GetValue(string key); } IValueProvide

viewstate

学习标签: ViewState 本文导读:在web窗体控件设置为runat = "server",这个控件会被附加一个隐藏的属性_ViewState,_ViewState存放了所有控件在ViewState中的状态值.ViewState是一个名称/值的对象集合.当请求某个页面时,ASP.NET会把所有控件的状态序列化成一个字符串,然后作为窗体的隐藏属性送到客户端,当客户端吧页面回传时,ASP.NET分析回传的窗体属性,并赋给控件对应的值. 当我们在写一个asp.net表单时, 一旦标明了

Struts 2.0全面分析

Struts 2.0 struts 1---前端控制+应用控制+命令模式 webwork ---控制器+拦截器+代理 Struts 2.0 继承了WebWork的设计理念,并没有继承struts 1,所以与struts 1是截然不同的~! ------------------------------------------------------- Struts 2.0的简单实例: web.xml中 <filter> <filter-name>struts2</filter-