1. Visual tree and logical tree
Logical tree: logic tree. The user interface in WPF is built with an object tree called logic tree. The declarative hierarchy of elements forms a so-called logic tree !!
Visual tree: A visual tree (also called a visual tree) is an extension of the logical tree. The visual tree splits the nodes of the logical tree into core tree components, it expresses some detailed visualization implementations, rather than treating each element as a "black box".
We use a simple program to observe the logical and visual trees:
<Window x:Class="WpfApplication28.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid> <Button Content="Button" HorizontalAlignment="Center" VerticalAlignment="Center"></Button> </Grid></Window>
There is only one button in the window. How can I view the logic tree and visual tree of this program? We can easily use a tool to view:
Tool for viewing the visual tree and logical tree in WPF: wpf inspector: http://wpfinspector.codeplex.com/
After the installation is complete, double-click to open the wpf inspector:
The software prompts that there are currently no running WPF applications. Now we start the WPF program:
An application named mainwindow was found. Click attach:
Visible tree on the left and logical tree on the right
It can be seen that the leaf node of the logicaltree is a control that forms the user interface. The structure of the logic tree is the declaration hierarchy of the control elements in the XAML, and the top is the application, the innermost layer is the button we created.
The visual tree contains more content that is not visible directly through the XAML, and the tiny structure of the control is also counted. Taking the button as an example, we can see that the button contains buttonchrome, creates a topic-specific appearance for a button. Buttonchrome contains the contentpressenter used to store a single sub-control, while contentpressenter stores a textblock used to display the text information on the button.
In addition, WPF inspector can view attributes, data binding, resources, styles, triggers, and other information in a WPF application.
You can use the tool to view the visual tree to gain a deeper understanding of the internal structure of the control.
2. Route events
Routing events: An event can be propagated up or down in the element tree and processed by the event handler along the propagation path. Routing events are routed based on the visual tree. routing events support three routing policies: Bubble, tunnel, and direct. Because they are propagated along the visual tree, the difference between routing events and winform is that, the event sender is not necessarily directly related to the event responder.
. Bubble (bubble) routing event: a routing event passed up the visible tree
If you add a border to the grid of mainwindow, add a textblock to the border, register the mouseleftbuttondown event for these controls respectively, and click textblock:
<Window x:Class="WpfApplication32.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid x:Name="Grid1" Background="CornflowerBlue" MouseLeftButtonDown="OnMouseLeftButtonDown"> <Border x:Name="Border1" Height="100" Width="200" Background="BurlyWood" MouseLeftButtonDown="OnMouseLeftButtonDown"> <TextBlock x:Name="TexlBlock1" Text="TextBlock" Background="Chartreuse" HorizontalAlignment="Center" VerticalAlignment="Center" Width="75" MouseLeftButtonDown="OnMouseLeftButtonDown"/> </Border> </Grid></Window>
Background code:
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { var fra = sender as FrameworkElement; MessageBox.Show(fra.Name); } }
The mouseleftbuttondown event of textblock is triggered first, then border, and finally grid.
If a widget does not support the events to be routed, you can use additional events. For example, stackpanel does not contain click events, you can add the following code:
<StackPanel Button.Click="ButtonBase_OnClick"> <Button Content="Button1"></Button> <Button Content="Button2"></Button> <Button Content="Button3"></Button> <Button Content="Button4"></Button> <CheckBox Content="Button5"></CheckBox> </StackPanel>
private void ButtonBase_OnClick(object sender, RoutedEventArgs e){var btn = e.Source as Button; if (btn == null) return; MessageBox.Show(btn.Content.ToString());}
When you click any button in stackpanel, this event can be passed up to stackpanel, so that you do not have to register a click event for all the buttons in stackpanel.
2. Tunnel routing events: Route events passed down the visible tree
All tunnel events start with Preview
<StackPanel PreviewMouseLeftButtonDown="UIElement_OnPreviewMouseLeftButtonDown"> <Button Content="Button1"></Button> <Button Content="Button2"></Button> <Button Content="Button3"></Button> <Button Content="Button4"></Button> <CheckBox Content="Button5"></CheckBox> </StackPanel>
Click the left mouse button at any button:
Sender: stackpanel
E. Source: button
E. originalsource: textblock
Note:
In general, all input events provided by WPF are implemented using Tunnel/bubble pairs, and tunnel events are always triggered before the bubble events;
To interrupt a route event, add E. Handled = true to the interrupt;
If the tunnel event is marked as handled, the bubble event will not occur again (routedeventarges of the two routing events is the same ).
. Direct routing event: only the event source has the opportunity to respond to the routing event
The event is only a routing event triggered on the Source Element, similar to the normal event processing method. The difference is that because it is still a routing event, it provides better support for WPF, and events will still participate in some specific routing event mechanisms, such as event triggers and class processing mechanisms.