惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Heimdal Security Blog
A
Arctic Wolf
K
Kaspersky official blog
V
Vulnerabilities – Threatpost
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Simon Willison's Weblog
Simon Willison's Weblog
L
LINUX DO - 热门话题
MongoDB | Blog
MongoDB | Blog
T
Threat Research - Cisco Blogs
D
Docker
爱范儿
爱范儿
T
Tenable Blog
C
Check Point Blog
B
Blog
C
Cisco Blogs
Vercel News
Vercel News
The Cloudflare Blog
T
Threatpost
NISL@THU
NISL@THU
T
Tor Project blog
V2EX - 技术
V2EX - 技术
P
Palo Alto Networks Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
T
Tailwind CSS Blog
G
GRAHAM CLULEY
P
Privacy & Cybersecurity Law Blog
SecWiki News
SecWiki News
博客园 - 司徒正美
S
Security @ Cisco Blogs
GbyAI
GbyAI
S
Secure Thoughts
Microsoft Security Blog
Microsoft Security Blog
The Register - Security
The Register - Security
Recorded Future
Recorded Future
Cloudbric
Cloudbric
Webroot Blog
Webroot Blog
N
News and Events Feed by Topic
Y
Y Combinator Blog
博客园_首页
T
Troy Hunt's Blog
The Hacker News
The Hacker News
雷峰网
雷峰网
Google DeepMind News
Google DeepMind News
U
Unit 42
AWS News Blog
AWS News Blog
PCI Perspectives
PCI Perspectives
V
Visual Studio Blog
博客园 - 聂微东
有赞技术团队
有赞技术团队
酷 壳 – CoolShell
酷 壳 – CoolShell

博客园 - dragonpig

Html 5 Canvas绘制分形图Mandelbrot .net中反射、emit、expression和dynamic的性能比较 const string 和 static readonly string的区别 SqlServer: Top N per Group 微软的BinarySearch 通过CTE实现Split CSV 通过SQL CTE计算Fibonacci 当json.js遇见dynamic.net烂尾篇 .NET线程安全泛型Singleton 跨域访问Cookie WCF JSON和AspnetCompatibility的配置 Windows安装Memcached node.js初体验 一道非常有趣的概率题 教你30秒打造强类型ASP.NET数据绑定 当json.js遇见dynamic.net [0] 用Silverlight做雷达图 C#运算符重载不是没有用武之地 随机排列算法
教你如何制作Silverlight Visual Tree Inspector
dragonpig · 2011-02-12 · via 博客园 - dragonpig

Silverlight中有Logic Tree和Visual Tree之分。比如在Xaml中定义了所有UI的logic结构,相当于模型。而运行时,显示的是UI的实际的物理结构。举个例子Button实际上是由更细粒度的UI如border和rectangle绘制成的。这里教大家制作一个 Inspector来动态检查Visual Tree的结构。先看一下实际效果(请按Inspect按钮):

效果不错,感觉有firebug的风范 :) 接下来看看关键技术。

  1. 高亮显示。很简单就是一个红色的Rectangle,当鼠标移动时把它放在当前UI Element的位置,设置相应的Position和Size就OK了。
  2. 如何获得UI的Visual Tree。使用VisualTreeHelper.GetChildrenCount(DependencyObject)可以获得所有Child Visual UI,通过VisualTreeHelper.GetChild(int)一一提取出来。最后递归调用所有子节点就可以反应出层次结构。
  3. 如何获得UI的坐标值。网上搜了一下发现UIElement.TransformToVisual可以办到。

感觉没啥更深奥的东西了,实际代码也就50行不到,你可以将左边栏换成自己的UserControl,检查一下他的Visual Tree是什么样子的(秉承个人博客的作风就是要精简巧妙,希望大家喜欢)

附赠源码:

XAML

<UserControl x:Class="SilverlightTutorial.InspectorPage"
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"><Canvas x:Name="LayoutRoot">
<Grid Background="Cornsilk" Height="400" Width="600">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel>
<Button Content="Button" Height="23" Name="button1" Width="75" />
<TextBlock Height="28" Name="label1" Width="120" Text="1234" />
<ListBox Height="100" Name="listBox1" Width="120">
<ListBoxItem>1</ListBoxItem>
<ListBoxItem>2</ListBoxItem>
<ListBoxItem>3</ListBoxItem>
<ListBoxItem>
<Button Content="Button" Height="23" Name="button2" Width="75" />
</ListBoxItem>
</ListBox>
</StackPanel>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="25" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ToggleButton Content="Inspect" HorizontalAlignment="Center" Name="btnInspect" />
<ScrollViewer VerticalScrollBarVisibility="Auto" Grid.Row="1">
<TextBlock Name="textBlock1" />
</ScrollViewer>
</Grid>
</Grid>
<Rectangle Name="rectHighlight" Stroke="Red" Width="100" Height="100" StrokeThickness="2" Visibility="Collapsed" />
</Canvas>
</UserControl>

CS

using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;namespace SilverlightTutorial
{
public partial class InspectorPage : UserControl
{
public InspectorPage()
{
InitializeComponent();
MouseMove
+= new MouseEventHandler(Page_MouseMove);
MouseLeftButtonUp
+= (sender, args) =>
{
btnInspect.IsChecked
= false;
rectHighlight.Visibility
= System.Windows.Visibility.Collapsed;
};
}
void Page_MouseMove(object sender, MouseEventArgs e)
{
var dpObj
= (e.OriginalSource as DependencyObject);
if ((bool)btnInspect.IsChecked == false || dpObj == null || dpObj == rectHighlight)
return;

Inspect(dpObj);

if (dpObj is UIElement)
{
var elm
= (dpObj as UIElement);
var generalTransform
= elm.TransformToVisual(null);
var point
= generalTransform.Transform(new Point());
SetHightlight(point, elm.RenderSize);
}
}
void SetHightlight(Point point, Size size)
{
rectHighlight.Visibility
= System.Windows.Visibility.Visible;
Canvas.SetLeft(rectHighlight, point.X);
Canvas.SetTop(rectHighlight, point.Y);
rectHighlight.Width
= size.Width;
rectHighlight.Height
= size.Height;
}
void Inspect(DependencyObject dpObj)
{
var sbuf
= new StringBuilder();
Inspect(sbuf,
0, dpObj);
textBlock1.Text
= sbuf.ToString();
}
void Inspect(StringBuilder sbuf, int level, DependencyObject dpObj)
{
sbuf.AppendLine(
new string(' ', 3 * level) + dpObj.GetType().Name);
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dpObj); i++)
{
Inspect(sbuf, level
+ 1, VisualTreeHelper.GetChild(dpObj, i));
}
}
}
}

PS. 有空会陆续把自己搜集的Silverlight知识做成系列,希望大家支持。