一、什么是邏輯樹
邏輯樹就是描述WPF界面元素的實際構成,它是由程序在XAML中所有的UI元素組成。最顯著的特點就是由布局控件、或者其他常用的控件組成。
1 <Window x:Class="WpfRouteEvent.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="MainWindow" Height="350" Width="525"> 5 <Grid> 6 <StackPanel> 7 <TextBox></TextBox> 8 </StackPanel> 9 </Grid> 10 </Window>
從上面的代碼中可以看出,Window、Grid、StackPanel、TextBox其實就是XAML界面的邏輯樹。
二、什么是可視樹
可視樹是由界面上可見的元素構成的,這些元素主要是由從Visual或者Visual3D類中派生出來的類。
上面代碼中的Window、Grid、StackPanel、TextBox它們本身就包含一些由Visual或者Visual3D類派生出的一些可視樹的元素來組成的。
三、邏輯樹和可視樹的遍歷
邏輯樹遍歷使用LogicalTreeHelper類。
可視樹遍歷使用VisualTreeHelper類。
演示遍歷邏輯樹和可視樹
1、XAML界面左邊顯示邏輯樹,右邊顯示可視樹,代碼如下:
1 <Window x:Class="WpfRouteEvent.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="MainWindow" Height="350" Width="525"> 5 <Grid> 6 <DockPanel> 7 <Button DockPanel.Dock="Top" Click="Button_Click" Content="獲取邏輯樹和可視樹"></Button> 8 <Grid> 9 <Grid.ColumnDefinitions> 10 <ColumnDefinition></ColumnDefinition> 11 <ColumnDefinition></ColumnDefinition> 12 </Grid.ColumnDefinitions> 13 <DockPanel Grid.Column="0"> 14 <TextBlock DockPanel.Dock="Top" Text="邏輯樹"></TextBlock> 15 <TreeView Name="tvLogicTree"></TreeView> 16 </DockPanel> 17 <DockPanel Grid.Column="1"> 18 <TextBlock DockPanel.Dock="Top" Text="可視樹"></TextBlock> 19 <TreeView Name="tvVisualTree"></TreeView> 20 </DockPanel> 21 </Grid> 22 </DockPanel> 23 24 </Grid> 25 </Window>
2、添加類,用於遍歷整個XAML界面的邏輯樹和可視樹
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Windows; 7 using System.Windows.Controls; 8 using System.Windows.Media; 9 10 namespace WpfRouteEvent 11 { 12 public class WpfTreeHelper 13 { 14 static string GetTypeDescription(object obj) 15 { 16 return obj.GetType().FullName; 17 } 18 19 /// <summary> 20 /// 獲取邏輯樹 21 /// </summary> 22 /// <param name="obj"></param> 23 /// <returns></returns> 24 public static TreeViewItem GetLogicTree(DependencyObject obj) 25 { 26 if (obj == null) 27 { 28 return null; 29 } 30 //創建邏輯樹的節點 31 TreeViewItem treeItem = new TreeViewItem {Header=GetTypeDescription(obj),IsExpanded=true }; 32 33 //循環遍歷,獲取邏輯樹的所有子節點 34 foreach (var child in LogicalTreeHelper.GetChildren(obj)) 35 { 36 //遞歸調用 37 var item = GetLogicTree(child as DependencyObject); 38 if (item != null) 39 { 40 treeItem.Items.Add(item); 41 } 42 } 43 44 return treeItem; 45 } 46 47 /// <summary> 48 /// 獲取可視樹 49 /// </summary> 50 /// <param name="obj"></param> 51 /// <returns></returns> 52 public static TreeViewItem GetVisualTree(DependencyObject obj) 53 { 54 if (obj == null) 55 { 56 return null; 57 } 58 59 TreeViewItem treeItem = new TreeViewItem { Header=GetTypeDescription(obj),IsExpanded=true}; 60 61 for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) 62 { 63 var child = VisualTreeHelper.GetChild(obj, i); 64 var item = GetVisualTree(child); 65 if (item != null) 66 { 67 treeItem.Items.Add(item); 68 } 69 } 70 71 return treeItem; 72 } 73 } 74 }
3、在按鈕的點擊事件中將獲取的邏輯樹和可視樹添加到XAML界面中
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Windows; 7 using System.Windows.Controls; 8 using System.Windows.Data; 9 using System.Windows.Documents; 10 using System.Windows.Input; 11 using System.Windows.Media; 12 using System.Windows.Media.Imaging; 13 using System.Windows.Navigation; 14 using System.Windows.Shapes; 15 16 namespace WpfRouteEvent 17 { 18 /// <summary> 19 /// MainWindow.xaml 的交互邏輯 20 /// </summary> 21 public partial class MainWindow : Window 22 { 23 public MainWindow() 24 { 25 InitializeComponent(); 26 } 27 28 private void Button_Click(object sender, RoutedEventArgs e) 29 { 30 this.tvLogicTree.Items.Add(WpfTreeHelper.GetLogicTree(this)); 31 this.tvVisualTree.Items.Add(WpfTreeHelper.GetVisualTree(this)); 32 } 33 } 34 }
4、點擊按鈕,界面運行效果