制作WPF好看的控件外观,必须要学会使用控件模板。了解控件模板就需要知道和了解逻辑树和可视化树。以下案例就是通过System.Windows.Media.VisualTreeHelper类来查看一个窗口的可视化数构成。先看一下运行效果:
通过一个递归遍历依次将当前控件的子元素通过TreeView展现出来。以下是核心代码:
VisualTreeDisplay.xaml
<Window x:Class="SimpleWindow.VisualTreeDisplay"
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"
xmlns:local="clr-namespace:SimpleWindow"
mc:Ignorable="d"
Title="VisualTreeDisplay" Height="412" Width="431">
<TreeView Name="treeElements" Margin="10"></TreeView>
</Window>
VisualTreeDisplay.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace SimpleWindow
{
/// <summary>
/// VisualTreeDisplay.xaml 的交互逻辑
/// </summary>
public partial class VisualTreeDisplay : Window
{
public VisualTreeDisplay()
{
InitializeComponent();
}
/// <summary>
/// 展示子元素
/// </summary>
/// <param name="element">当前的元素</param>
public void ShowVisualTree(DependencyObject element)
{
treeElements.Items.Clear();
ProcessElement(element, null);
}
/// <summary>
/// 递归出所有元素的子节点,并展示出来。
/// </summary>
/// <param name="element">当前遍历的元素</param>
/// <param name="previousItem">当前节点的父元素</param>
public void ProcessElement(DependencyObject element,TreeViewItem previousItem)
{
TreeViewItem item = new TreeViewItem();
item.Header = element.GetType().Name;
item.IsExpanded = true;
if(previousItem == null)
{
// 根节点情况
treeElements.Items.Add(item);
}
else
{
// 子节点情况
previousItem.Items.Add(item);
}
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element);i++)
{
// 递归调用进行遍历当前元素的子节点。
ProcessElement(VisualTreeHelper.GetChild(element,i), item);
}
}
}
}
Main.xaml:
<Window x:Class="SimpleWindow.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"
xmlns:local="clr-namespace:SimpleWindow"
mc:Ignorable="d"
Title="获取当前窗口可视化元素" Height="338" Width="356">
<Window.Resources>
<Style TargetType="Button">
<Setter Property="Width" Value="300"></Setter>
<Setter Property="Height" Value="30"></Setter>
<Setter Property="Margin" Value="5"></Setter>
<Setter Property="Foreground" Value="Red"></Setter>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0 0" EndPoint="0.5 1">
<GradientStop Color="White" Offset="0.15"/>
<GradientStop Color="LightBlue" Offset="1"></GradientStop>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="5">
<ContentControl
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Cursor="{TemplateBinding Cursor}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
FontStretch="{TemplateBinding FontStretch}"
Foreground="{TemplateBinding Foreground}"
IsTabStop="{TemplateBinding IsTabStop}"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"
>
</ContentControl>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel Margin="5">
<Button Padding="5" Margin="5" Click="cmd_Click" Content="First Button"></Button>
<Button Padding="5" Margin="5" Click="cmd_Click" Content="Second Button"></Button>
</StackPanel>
</Window>
完整项目及控件样式详见工程路径:https://download.csdn.net/download/chulijun3107/19120894