当我们拖动WPF控件时,我们为了更清楚地需要显示控件,一般我们会在WPF控件所围成的矩形区域的四个边界点上作一个特殊的记号(比如圆点)。如下图:
在Winform中,我们一般都是先找到控件所包围的矩形区域,然后画出四个边界点。那么,在WPF,如何显示这四个边界点呢?
答案是使用Adorner。Adorner是继承自FrameworkElement的抽象类:
public abstract class Adorner : FrameworkElement
首先,我们建立一个CircleAdorner类,它继承自Adorner:
//CircleAdorner.cs
using System;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
namespace BrawDraw.Com.WPF
{
public class CircleAdorner : Adorner
{
public CircleAdorner(UIElement adornedElement)
: base(adornedElement)
{
}
protected override void OnRender(DrawingContext drawingContext)
{
//找出控件所围成的矩形区域
Rect adornedElementRect = new Rect(this.AdornedElement.DesiredSize);
SolidColorBrush renderBrush = new SolidColorBrush(Colors.Red);
renderBrush.Opacity = 1.0;
Pen renderPen = new Pen(new SolidColorBrush(Colors.Red), 0.5);
double renderRadius = 3.0;
drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.TopLeft, renderRadius, renderRadius);
drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.TopRight, renderRadius, renderRadius);
drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.BottomLeft, renderRadius, renderRadius);
drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.BottomRight, renderRadius, renderRadius);
}
}
}
上面这个类的作用是对相应控件的“附加绘制”,它画出控件的四个顶点。这里的OnRender相当于GDI+中的OnPaint。
下面我们对一个TextBox,一个包含于StackPanel中的Button和TextBox, 以及包含于Canvas中的Path进行“附加绘制”。
先看看XAML代码:
// Window1.xaml
Title="CircleAdornerDemo" Loaded="WindowLoaded" Height="464" Width="625"
>
Name="myTextBox"
Height="50" Width="150"
Grid.Row="0"
Text="这是一个TextBox."
/>
Name="myButton1"
Width="150"
Content="Adorned Button"
/>
下面是控制代码:
// Window1.xaml.cs
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Collections;
namespace BrawDraw.Com.WPF
{
public partial class Window1 : Window
{
AdornerLayer myAdornerLayer;
public Window1()
{
InitializeComponent();
}
private void WindowLoaded(object sender, RoutedEventArgs e)
{
myAdornerLayer = AdornerLayer.GetAdornerLayer(myTextBox);
myAdornerLayer.Add(new CircleAdorner(myTextBox));
foreach (UIElement toAdorn in myStackPanel.Children)
{
myAdornerLayer.Add(new CircleAdorner(toAdorn));
}
foreach (UIElement toAdorn in myCanvas.Children)
{
myAdornerLayer.Add(new CircleAdorner(toAdorn));
}
}
}
}
注意:这里使用AdornerLayer.Add(new CircleAdorner(UIElement))方法来完成这种附加。