使用Adorner顯示WPF控制元件的邊界點
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
當我們拖動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
<Window x:Class="BrawDraw.Com.WPF.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="CircleAdornerDemo" Loaded="WindowLoaded" Height="464" Width="625"
>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="80"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBox
Name="myTextBox"
Height="50" Width="150"
Grid.Row="0"
Text="這是一個TextBox."
/>
<StackPanel Name="myStackPanel" Grid.Row="1">
<Button
Name="myButton1"
Width="150"
Content="Adorned Button"
/>
<TextBox Grid.Row="1" Name="textBox1" Height="100" Width="220" />
</StackPanel>
<Canvas Margin="51,141,162,59" Name="myCanvas" Grid.Row="1">
<Path StrokeThickness="1.000000" Stroke="#fffa0e0b" StrokeMiterLimit="1.000000" Data="F1 M 100.295898,66.248535 C 100.295898,66.248535 44.894531,33.529785 68.517578,66.316895 C 92.140137,99.104004 197.243164,6.331055 274.625000,133.188477 C 366.679688,46.227051 378.309570,2.718750 359.714844,25.067383"/>
</Canvas>
</Grid>
</Window>
下面是控制程式碼:
// 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))方法來完成這種附加。