之前讨论了WPF的根本架构,然后逐步开始学习构造面板,转换,介绍了差此外控件,容器,UI转换等。在这篇文章中,我将讨论每个创建XAML应用前的开发人员应该了解的关于XAML最重要的对象。
符号扩展是一种对XAML的扩展,你可以用来对基于XAML的措施应用自界说的法则。在你的设计中,你如果有任何的想对你的措施施加的自界说行为,你都可以使用符号扩展来实现。这里我们将讨论你可以怎样使用符号扩展对XAML生成自界说的行为。
XAML或者说可扩展应用措施符号语言实际上是一种界说了特殊架构的XML格局的语言。此刻你可能经常想知道,符号到底能怎样扩展。XAML中到底有什么样的能力使其与XML大不不异。似的,它是因为有着大量的成果的XAML转换器把普通的XAML转换成了饱满的UI设计。
大家都知道XAML实际上是文本格局。它的标签和XML非常相似,每个属性的值都是字符串。尽管你想把一个东西赋给一个字符串,但是因为东西只能有一个字符串,所以你不能这样做。符号扩展将允许你措置惩罚惩罚这些情况。所以你可以说一个符号扩展实际上是一种把普通的XML扩展成为一个完成的可扩展的符号的方法——便是XAML。
由于XAML把任何对象都当成字符串,有事我们需要把这些字符串转换为有效的值。举个例子:当我们使用 Margin 的时候,我们需要声明 margin 元素的每个值。在这种情况下,转换非常的简单和直接,我们可以使用类型转换器而不是使用符号扩展。在我们讨论符号扩展前,首先我们来讨论一下类型转换器。
类型转换器
在上文中我已经说过了,XML的符号扩展不能对元素的数据施加限制。意思就是你在XAML中只能声明东西的属性为字符串数据。但是XAML供给了一个灵活的方法来创建类型转换器,这样就可以对数据施加限制了。甚至像 Single 和 Double这样的原语你都不能在XAML中描述。类型转换器饰演了一个重要的角色来把这种限制加到XAML转换器上。
XAML转换器在转换任何属性的值时需要两个信息:
值类型:这个决定了值将被转换为什么类型
真实值
好的,当转换器找到一个属性中的数据时,它首先确定数据的类型。如果类型是根基的,转换器将测验考试直接转换。另一方面,如果是一个可枚举类型,转换器将测验考试转换为一个特定的枚举值。如果上面的都不满足,转换器将测验考试找到一个合适的类型转换器类并转换为一个合适的类型。XAML中已经界说了许多的类型转换器,好比 Margin=10,20,0,30 意思就是凭据左,上,右,下界说的一个序列。因此系统界说了一个转换器把这种数据转换为 Thickness 东西。
自界说类型转换器
要创建一个自界说的类型转换器,我们需要使用 TypeConverterAttribute 装饰类型并且自界说一个用来把数据转换为实际类型的类。实际转换的类,需要担任自 TypeConverter 。
让我们使用一个例子来说得更大白:
一个转换地舆位置的类型转换器:
像我上面说的那样,为了创建一个类型转换器,你需要创建一个一个应用了 TypeConverter 的类。在我的例子中,我创建了一个有两个属性 Latitude(纬度) 和 Longitude(经度) 的类,并且创建了一个地舆位置的实现。让我们看一下以下的类:
[global::System.ComponentModel.TypeConverter(typeof(GeoPointConverter))] public class GeoPointItem { public double Latitude { get; set; } public double Longitude { get; set; } public GeoPointItem() { } public GeoPointItem(double lat, double lon) { this.Latitude = lat; this.Longitude = lon; } public static GeoPointItemParse(string data) { if (string.IsNullOrEmpty(data)) return new GeoPointItem(); string[] items = data.Split(‘,‘); if (items.Count() != 2) throw new FormatException("GeoPoint should have both latitude and longitude"); double lat, lon; try { lat = Convert.ToDouble(items[0]); } catch (Exception ex) { throw new FormatException("Latitude value cannot be converted", ex); } try { lon = Convert.ToDouble(items[1]); } catch (Exception ex) { throw new FormatException("Longitude value cannot be converted", ex); } return new GeoPointItem(lat, lon); } public override string ToString() { return string.Format("{0},{1}", this.Latitude, this.Longitude); } }