視圖邏輯樹狀結構:
說明:
WPF使用者介面元素之間有等級關係,這種關係叫邏輯樹狀結構。一個元素的模板可以有多個元素組成,這個叫做視圖樹。WPF兩個樹之間的差距在於對有些問題,你僅僅需要邏輯樹狀結構,而有些問題都需要。
<Window> <Grid> <Label Content="Label" /> <Button Content="Button" /> </Grid></Window>
為什麼我們需要兩種不同的樹:
WPF控制項由多個較原始的控制群組成。例如:按鈕(Button)是由邊框(Border)、矩形(Rectangle)和內容(Content)組成。它們應該是按鈕(Button)的視圖子控制項。當WPF要顯示一個按鈕(Button)時,元素本身是不會顯示的,但它會遍曆它的視圖樹把它的子項目顯示出來。這種等級關係也可用於點擊測試和布局。
然而,有時候你並不關注控制項範本的邊框和形狀。主要是因為該模板將會在運行時被取代,從而你不用涉及視圖樹的結構。你將需要的是一個更豐富的樹,它包含著真正的控制項,而不是模板部分。這就是邏輯樹狀結構的表現。
邏輯樹狀結構:
邏輯樹狀結構描述的是使用者介面元素之間的關係,它主要負責:
- 傳承相依性屬性的值
- 設定動態資源的引用
- 為綁定查詢元素的名稱
- 傳遞路由事件
視圖樹:
視圖樹包括每一個邏輯元素的模板中的所有視圖元素。它的責任是:
- 顯示視圖元素
- 設定元素的透明度
- 設定元素的布局和渲染變化
- 設定元素的可用(IsEnable)屬性
- 做點擊測試
- 關聯資源(尋根)
視圖樹中的尋根編碼:
如果使用者介面中的子項目要訪問父元素中的資料,但你不到這中間有多少代關係。最好的解決方案就是遍曆整個樹直到找到所需類型的元素。
這是一個比較準確的協助程式,你幾乎不用修改任何地方就能找出來。
代碼
public static class VisualTreeHelperExtensions
{
public static T FindAncestor<T>(DependencyObject dependencyObject)
where T : class
{
DependencyObject target = dependencyObject;
do
{
target = VisualTreeHelper.GetParent(target);
}
while (target != null && !(target is T));
return target as T;
}
}
下面的例子示範了怎樣使用這個協助程式。它從this開始直到找出Grid類型的元素為止。如果它到達了樹的根項目還沒找到,則返回NULL。
var grid = VisualTreeHelperExtensions.FindAncestor<Grid>(this);