WPF基礎知識

本篇介紹WPF基礎知識,包括類層次結構、命名空間、類型轉換器、邏輯樹與可視樹等等。


1. WPF類層次結構



2. XAML命名空間

XAMLXML-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自定義控件dllCLR命名空間引用方式爲:
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));
}

注意點:

假如不重寫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));
	}
}
效果:

邏輯樹:



可視樹:





作者:FoolRabbit
出處:http://blog.csdn.net/rabbitsoft_1987
歡迎任何形式的轉載,未經作者同意,請保留此段聲明!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章