本篇介绍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));
}
}
效果:
逻辑树:
可视树:
作者:FoolRabbit
出处:http://blog.csdn.net/rabbitsoft_1987
欢迎任何形式的转载,未经作者同意,请保留此段声明!