本篇介紹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>
定義一個 MyControl 自定義控件 dll , CLR 命名空間引用方式為:
- CLR命名空間與URL辨別命名空間。
在 AssemblyInfo .cs 代碼檔案中添加 URL 命名空間關聯xmlns:control1="clr-namespace:MyControl;assembly=MyControl"
URL 命名控件引用方式為[assembly: XmlnsDefinition("http://test/MyControl", "MyControl")]
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
歡迎任何形式的轉載,未經作者同意,請保留此段聲明!