天天看点

WPF基础知识1. WPF类层次结构2. XAML命名空间3.类型转换器4.标记扩展5.逻辑树与可视树

本篇介绍WPF基础知识,包括类层次结构、命名空间、类型转换器、逻辑树与可视树等等。

1. WPF类层次结构

WPF基础知识1. WPF类层次结构2. XAML命名空间3.类型转换器4.标记扩展5.逻辑树与可视树

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 命名空间引用方式为:
xmlns:control1="clr-namespace:MyControl;assembly=MyControl"
           
在 AssemblyInfo .cs 代码文件中添加 URL 命名空间关联
[assembly: XmlnsDefinition("http://test/MyControl", "MyControl")]
           
URL 命名控件引用方式为
xmlns:control2="http://test/MyControl"
           

注意,假如定义了 URL 命名空间关联,在智能提示中, CLR 命名空间不再显示,不过还是有效的。

添加默认的命名空间前缀:

[assembly: XmlnsPrefix("http://test/MyControl", "control")]
           

3.类型转换器

XAML中都是通过字符串来设定值的,类型转换器的作用就是将字符串转化为相应的CLR对象,譬如将White转化为对应的颜色值。

所有的类型转化器都派生自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));
}
           
WPF基础知识1. WPF类层次结构2. XAML命名空间3.类型转换器4.标记扩展5.逻辑树与可视树

注意点:

假如不重写CanConvertFrom方法,编译运行能成功,但是会提示:“Human”的 TypeConverter 不支持从字符串进行转换。

4.标记扩展

标记扩展,就像类型转换器一样,可以用于扩展XAML的表达能力。它们都可以在运行时计算字符串特性的值(除了一些内建的、为提高性能而在编译时计算的标记扩展),并生成一个合适的基于字符串的对象。就像类型转换器一样,WPF有好几个内建的标记扩展,你会发现它们都派生自本书最前面的内封中的MarkupExtension。

标记扩展实际上是一种特殊的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中的内容)不会包含在内,因为它们自己并没有与生俱来的呈现行为。

相同的逻辑树,不同的主题,相对应的可视树可能就不同。

下面代码打印出程序的逻辑树与可视树:

//打印逻辑树
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));
	}
}
           

效果:

逻辑树:

WPF基础知识1. WPF类层次结构2. XAML命名空间3.类型转换器4.标记扩展5.逻辑树与可视树

可视树:

WPF基础知识1. WPF类层次结构2. XAML命名空间3.类型转换器4.标记扩展5.逻辑树与可视树

代码

作者:FoolRabbit

出处:http://blog.csdn.net/rabbitsoft_1987

欢迎任何形式的转载,未经作者同意,请保留此段声明!

继续阅读