WPF基础知识
本篇介绍WPF基础知识,包括类层次结构、命名空间、类型转换器、逻辑树与可视树等等。
1. WPF类层次结构
2. XAML命名空间
XAML是XML-Namespace的缩写。知识点:
- 冒号后面的映射名可有可无,不加映射名的即为默认命名空间,这种命名空间仅能有一个。系统默认将http://schemas.microsoft.com/winfx/2006/xaml/presentation作为默认命名空间。
- 命名空间有属性值继承的功能,父级引用的命名空间子级能直接使用。如下:
- <Grid xmlns:s="clr-namespace:System;assembly=mscorlib">
- <Button>
- <s:String>Test</s:String>
- </Button>
- </Grid>
- CLR命名空间与URL标识命名空间。
定义一个MyControl自定义控件dll,CLR命名空间引用方式为:在AssemblyInfo.cs代码文件中添加URL命名空间关联
- xmlns:control1="clr-namespace:MyControl;assembly=MyControl"
URL命名控件引用方式为
- [assembly: XmlnsDefinition("http://test/MyControl", "MyControl")]
注意,假如定义了URL命名空间关联,在智能提示中,CLR命名空间不再显示,不过还是有效的。
- xmlns:control2="http://test/MyControl"
添加默认的命名空间前缀:
- [assembly: XmlnsPrefix("http://test/MyControl", "control")]
3.类型转换器
XAML中都是通过字符串来设定值的,类型转换器的作用就是将字符串转化为相应的CLR对象,譬如将White转化为对应的颜色值。
所有的类型转化器都派生自TypeConverter。TypeConverter提供的4个重要的方法是CanConvertTo、CanConvertFrom、ConvertTo(CLR对象->字符串)和ConvertFrom(字符串->CLR对象)。
自定义类型转换器(人员管理,人员隶属于哪个上级人员):
自定义转换器代码:
所有的类型转化器都派生自TypeConverter。TypeConverter提供的4个重要的方法是CanConvertTo、CanConvertFrom、ConvertTo(CLR对象->字符串)和ConvertFrom(字符串->CLR对象)。
自定义类型转换器(人员管理,人员隶属于哪个上级人员):
自定义转换器代码:
- private void AddControl()
- {
- Label label = new Label();
- label.Content = "通过代码添加";
- mainGird.Children.Add(label);
- Grid.SetColumn(label, 0);
- Grid.SetRow(label, 1);
- }
- public class StringToHumanTypeConverter : TypeConverter
- {
- public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
- {
- if(value is string)
- {
- Human human = new Human();
- human.Name = (string)value;
- return human;
- }
- return base.ConvertFrom(context, culture, value);
- }
- public override bool CanConvertFrom(ITypeDescriptorContext context, System.Type sourceType)
- {
- return true;
- //return base.CanConvertFrom(context, sourceType);
- }
- }
资源代码:
- <Window.Resources>
- <local:Human x:Key="human" Name="child" Parent="parent"/>
- </Window.Resources>
- private void Button_Click(object sender, RoutedEventArgs e)
- {
- Human human = (Human)this.FindResource("human");
- MessageBox.Show(string.Format("子级:{0},父级:{1}", human.Name, human.Parent.Name));
- }
注意点:
假如不重写CanConvertFrom方法,编译运行能成功,但是会提示:“Human”的 TypeConverter 不支持从字符串进行转换。
4.标记扩展
标记扩展,就像类型转换器一样,可以用于扩展XAML的表达能力。它们都可以在运行时计算字符串特性的值(除了一些内建的、为提高性能而在编译时计算的标记扩展),并生成一个合适的基于字符串的对象。就像类型转换器一样,WPF有好几个内建的标记扩展,你会发现它们都派生自本书最前面的内封中的MarkupExtension。
标记扩展实际上是一种特殊的Attribute=Value语法,特殊之处在于Value字符串由一对花括号及其括起来的内容组成。XMAL编译器对这样的内容进行解析、生成相应的对象。
如下就是标记扩展用法:
摆脱花括号,假如输出文本正好包含一对花括号,而又不是扩展标记,怎么输出花括号呢?
可以通过在其之前增加一对空花括号来实现。如下:
标记扩展实际上是一种特殊的Attribute=Value语法,特殊之处在于Value字符串由一对花括号及其括起来的内容组成。XMAL编译器对这样的内容进行解析、生成相应的对象。
如下就是标记扩展用法:
- <Button Background="{x:Null}" Content="{Binding XXX}" />
可以通过在其之前增加一对空花括号来实现。如下:
- <Button Content="{}{我是花括号!}" />
5.逻辑树与可视树
在WPF中,用户界面由一个对象树构建而成,这棵树叫作逻辑树。
可视树基本上是逻辑树的扩展,在可视树中,节点都被打散,分放到核心可视组件中。
并非所有的逻辑树节点都会出现在可视树中,只有从System.Windows.Media.Visual或System.Windows.Media.Visual3D派生的元素才会被包含进去。其他元素(和一些简单的字符串内容,如代码清单3-1中的内容)不会包含在内,因为它们自己并没有与生俱来的呈现行为。
相同的逻辑树,不同的主题,相对应的可视树可能就不同。
下面代码打印出程序的逻辑树与可视树:
可视树基本上是逻辑树的扩展,在可视树中,节点都被打散,分放到核心可视组件中。
并非所有的逻辑树节点都会出现在可视树中,只有从System.Windows.Media.Visual或System.Windows.Media.Visual3D派生的元素才会被包含进去。其他元素(和一些简单的字符串内容,如代码清单3-1中的内容)不会包含在内,因为它们自己并没有与生俱来的呈现行为。
相同的逻辑树,不同的主题,相对应的可视树可能就不同。
下面代码打印出程序的逻辑树与可视树:
- //打印逻辑树
- private void PrintLogicalTree(int dept, object obj)
- {
- //前置空格标识深度
- Debug.WriteLine(new string(' ', dept) + obj);
- if (!(obj is DependencyObject))
- {
- return;
- }
- foreach (object child in LogicalTreeHelper.GetChildren(obj as DependencyObject))
- {
- PrintLogicalTree(dept + 1, child);
- }
- }
- //打印可视树
- private void PrintVisualTree(int dept, DependencyObject obj)
- {
- //前置空格标识深度
- Debug.WriteLine(new string(' ', dept) + obj);
- for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
- {
- PrintVisualTree(dept + 1, VisualTreeHelper.GetChild(obj, i));
- }
- }
逻辑树:
可视树:

浙公网安备 33010602011771号