原文:使用Adorner显示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))方法来完成这种附加。

使用Adorner显示WPF控件的边界点相关推荐

  1. WPF显示经常使用的几个显示文字控件TextBox, TextBlock, Lable

    WPF显示经常使用的几个显示文字控件TextBox, TextBlock, Lable TextBox, TextBlock. Lable 当中TextBox 和Lable均继承了Control类 能 ...

  2. 日志查看器:显示日志记录信息的快速WPF控件

    对于长时间运行的后台任务,用户了解当前执行的步骤很有帮助.LogViewer可以安全地多线程收集此信息,并将其显示为可滚动文本.LogViewer允许后台线程在不使用任何WPF代码的情况下写入格式化文 ...

  3. WPF 组态软件实现思路(WPF控件可视化布局)

    WPF 开源 组态软件实现思路(WPF控件可视化布局) 一.实现控件选中及自由拖动 二.实现控件对齐功能 三.实现对齐辅助线功能 四.实现框选功能 GitHub地址点此 请注意 属性编辑控件基于Dev ...

  4. wpf控件设计时支持(2)

    原文:wpf控件设计时支持(2) 这篇介绍在wpf设计时集合项属性添加项的定义和自定义控件右键菜单的方法 集合项属性设计时支持 1.为集合属性设计器识别具体项类型 wpf设计器允许定义集合项的类型,如 ...

  5. wpf控件开发基础(1)

    从现在开始,我将尝试写有关wpf控件开发相关的知识,把文章这对我来说很难,所以这个系列的文章在时间跨度上可能会拖的比较长.我希望我介绍是比较详细的,而不仅仅是一个简单的控件开发流程.我是一个真正的We ...

  6. 在WinForm应用程序中嵌入WPF控件(转)

      我们知道,在WPF界面上添加WinForm的控件需要使用WindowsFormHost类.而在WinForm界面上添加WPF控件该如何做呢?有没有类似的类呢?明显是有的,ElementHost就是 ...

  7. [转] 使用模板自定义 WPF 控件

      [转] 使用模板自定义 WPF 控件                                                                                 ...

  8. WPF 控件库——仿制Windows10的进度条

    WPF 控件库--仿制Windows10的进度条 原文:WPF 控件库--仿制Windows10的进度条 一.其实有现成的 先来看看Windows10进度条的两种模式: 网上有不少介绍仿制Window ...

  9. WPF开发人员必读:WPF控件测试台

    介绍 WpfControlTestbench帮助您为您的控件或您想要调查其行为的任何控件编写快速复杂的测试窗口.只需十几行XAML即可创建以下Window内容: 它在左下角显示你要测试的控件,在Win ...

  10. 开源WPF控件库-AdonisUI

    原文:https://github.com/benruehl/adonis-ui 翻译:沙漠尽头的狼(谷歌翻译加持) 用于 WPF 应用程序的轻量级 UI 工具包,提供经典和增强的 Windows 视 ...

最新文章

  1. 邀请了阿里的学长学姐分享
  2. echart的关系图高亮_echarts鼠标覆盖高亮显示节点及关系名称详解
  3. 保姆级教程:Spring Boot 单元测试
  4. [linux]cp和mv对文件和链接影响的区别
  5. 使用Apache Camel 2.14的轻松REST端点
  6. python精确小数点_如何确定小数点是否可以精确地表示为Python float?
  7. 基础总结篇之八:创建及调用自己的ContentProvider
  8. VMware 安装 Linux---错误-未找到要在其中创建新文件系统的有效设备
  9. 2022年Python最新面试题汇总及答案
  10. 通过DMA方式进行连续发送
  11. AI+社区智能管理,赋能智慧城市人情共「智」
  12. sdust-Java-字符串集合求并集
  13. 【C语言】[其他] :code, data, idata, xdata, bdata, edata, hdata等,代表的意思
  14. GLUT, freeGLUT, GLFW, GLEW, GLAD 关系与区别
  15. 【菜鸟窝】Hadoop生态系统、Hadoop虚拟机环境准备、Hadoop环境搭建(含安装包和教程)
  16. Java之-MyBatis
  17. XMAN【我真的好菜-同pizza师傅修炼笔记四】hackcon-app.exe
  18. 机器学习领域定会顶刊
  19. 机器学习——凸优化基础知识
  20. Windows CE 模拟器和远程调试工具

热门文章

  1. python语言用什么编译器_如何修改python语言pycharm工具的默认编译器
  2. 2060显卡驱动最新版本_堪比显卡界中的小米,价格屠夫,1999的铭瑄RTX2060终结者体验...
  3. php如何判断一个类是否存在,PHP利用判断类是否存在函数class_exists用法的简单示例...
  4. Java覆盖率模拟protected,单元测试覆盖率-使用Clover
  5. java虚拟机的gc机制的优缺点_深入Java虚拟机之 -- 总结面试篇
  6. Python中如何安装pip,xlrd
  7. HashMap、LinkedHashMap、HashTable、HashSet笔记
  8. [saiku] 将saiku自带的H2嵌入式数据库迁移到本地mysql数据库
  9. ios开发错误之: Undefined symbols for architecture x86_64
  10. 微信服务号/企业号防止AccessToken过期的操作指南深入浅出