使用Adorner显示WPF控件的边界点

简介: 原文:使用Adorner显示WPF控件的边界点 当我们拖动WPF控件时,我们为了更清楚地需要显示控件,一般我们会在WPF控件所围成的矩形区域的四个边界点上作一个特殊的记号(比如圆点)。
原文: 使用Adorner显示WPF控件的边界点

当我们拖动WPF控件时,我们为了更清楚地需要显示控件,一般我们会在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)方法来完成这种附加。

目录
相关文章
|
1月前
|
C# 开发者 Windows
基于Material Design风格开源、易用、强大的WPF UI控件库
基于Material Design风格开源、易用、强大的WPF UI控件库
|
5月前
|
C#
浅谈WPF之装饰器实现控件锚点
使用过visio的都知道,在绘制流程图时,当选择或鼠标移动到控件时,都会在控件的四周出现锚点,以便于修改大小,移动位置,或连接线等,那此功能是如何实现的呢?在WPF开发中,想要在控件四周实现锚点,可以通过装饰器来实现,今天通过一个简单的小例子,简述如何在WPF开发中,应用装饰器,仅供学习分享使用,如有不足之处,还请指正。
66 1
|
9月前
|
C# Windows
WPF技术之图形系列Polygon控件
WPF Polygon是Windows Presentation Foundation (WPF)框架中的一个标记元素,用于绘制多边形形状。它可以通过设置多个点的坐标来定义多边形的形状,可以绘制任意复杂度的多边形。
484 0
|
9月前
|
C# Windows
WPF技术之RichTextBox控件
WPF RichTextBox是Windows Presentation Foundation (WPF)中提供的一个强大的文本编辑控件,它可以显示富文本格式的文本,支持多种文本处理操作。
358 0
|
5月前
|
前端开发 C# 容器
浅谈WPF之控件拖拽与拖动
使用过office的visio软件画图的小伙伴都知道,画图软件分为两部分,左侧图形库,存放各种图标,右侧是一个画布,将左侧图形库的图标控件拖拽到右侧画布,就会生成一个新的控件,并且可以自由拖动。那如何在WPF程序中,实现类似的功能呢?今天就以一个简单的小例子,简述如何在WPF中实现控件的拖拽和拖动,仅供学习分享使用,如有不足之处,还请指正。
116 2
|
9月前
|
数据挖掘 数据处理 C#
WPF技术之DataGrid控件
WPF DataGrid是一种可以显示和编辑数据的界面控件。它可以作为表格形式展示数据,支持添加、删除、修改、排序和分组操作。
189 0
|
1月前
|
C# 开发者 C++
一套开源、强大且美观的WPF UI控件库
一套开源、强大且美观的WPF UI控件库
142 0
|
6月前
|
算法 C# UED
浅谈WPF之控件模板和数据模板
WPF不仅支持传统的Windows Forms编程的用户界面和用户体验设计,同时还推出了以模板为核心的新一代设计理念。在WPF中,通过引入模板,将数据和算法的“内容”和“形式”进行解耦。模板主要分为两大类:数据模板【Data Template】和控件模板【Control Template】。
105 8
|
9月前
|
定位技术 C# UED
WPF技术之ScrollViewer控件
WPF ScrollViewer是WPF中常用的一个控件,它提供了滚动视图的功能,可用于显示超出容器可视区域的内容。ScrollViewer通常用于容纳大量内容的控件,以在有限的空间内显示这些内容,并允许用户通过滚动来查看隐藏的部分。
783 0
|
9月前
|
前端开发 C#
WPF技术之ContentControl 控件
ContentControl 是 WPF 中的一个常见控件,用于显示单个内容元素。它可以包含任意类型的内容,包括文本、图像、控件等。
827 0