介绍概念之前,先来分析一段代码:
xaml代码如下:
<Window x:Class="WpfApp1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <UniformGrid x:Name="grid"> <Button Height="30" Width="120" > <StackPanel> <Image/> <TextBlock>Clack</TextBlock > </StackPanel> </Button> <Button Height="30" Width="120" > <StackPanel> <Image/> <TextBlock>Clack</TextBlock > </StackPanel> <Button.Template > <ControlTemplate TargetType =‘Button‘> <ContentPresenter Content =‘{TemplateBinding Content }‘/> </ControlTemplate > </Button.Template > </Button> </UniformGrid> </Window>
xaml.cs代码如下:
using System.Windows; using System.Windows.Controls; namespace WpfApp1 { /// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); this.Loaded += MainWindow_Loaded; } private void MainWindow_Loaded(object sender, RoutedEventArgs e) { Image image = new Image(); TextBlock textBlock = new TextBlock(); textBlock.Text = "Clack"; StackPanel stackPanel = new StackPanel(); stackPanel.Children.Add(image); stackPanel.Children.Add(textBlock); Button button = new Button(); button.Width = 100; button.Height = 30; button.Content = stackPanel; this.grid.Children.Add(button); } } }
运行之后:
接下来我们把xaml及xaml.cs中的代码合起来的逻辑树和代码运行后呈现的可视化树画出来:
通过上面对比,下面看出几个特点:
1、Button的Content内容,是在Button的Templete控件模板中的ContentPresenter中呈现的。
2、逻辑树中展示出来的不是所有的节点,1、3的Button也都有ContentPresenter等隐藏未显示。
3、逻辑树的节点,在可视化树的结构中都有表现,且可视化树表现出更多的节点。
4、逻辑树表现出来"界面"的构建过程、而可视化树表现出了“界面”的构建结构。
MSDN中介绍逻辑树在 WPF 框架级别,即FrameworkElement 或 FrameworkContentElement)类级别。可以使用LogicalTreeHelper进行逻辑树中对象的遍历查找。
可视化树(Visual Tree)则是基于Visual基类,Visual基类的主要角色是提供呈现支持,包括输出显示、转换、裁剪、命中测试、边框计算。可以使用VisualTreeHelper来遍历可视化树。
可以参考WPF体系结构。