原文:使用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. 浅尝辄止——使用ActiveX装载WPF控件

    1 引言 使用VC编写的容器类编辑器,很多都可以挂接ActiveX控件,因为基于COM的ActiveX控件不仅封装性不错,还可以显示一些不错的界面图元. 但是随着技术不断的进步,已被抛弃的Active ...

  2. WPF 控件被禁用,悬浮提示不显示问题

    原文:WPF 控件被禁用,悬浮提示不显示问题 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/BYH371256/article/details/89 ...

  3. WPF通过不透明蒙板切割显示子控件

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/Backspace110/article/ ...

  4. XMAL语法系列之-(2)---WPF控件继承图

    WPF控件继承图 1 FrameworkElement 1.1 Panel(面板类元素) 1.1.1 Canvas 1.1.2 DockPanel 1.1.3 Grid 1.1.4 TabPanel ...

  5. WPF控件模板

    引言:在进行WPF项目开发过程中,由于项目的需要,经常要对某个控件进行特殊的设定,其中就牵涉到模板的相关方面的内容.本文也是在自己进行项目开发过程中遇到控件模板设定时集中搜集资料后整理出来的,以供在以 ...

  6. Dev的WPF控件与VS2012不兼容问题

    在只有vs2010环境下Dev的wpf可以在视图模式下显示,但是安装vs2012后无法打开界面的视图模式,报错:无法创建控件实例! 发现是Dev的wpf控件与.net framework 4.5不兼容 ...

  7. Sparrow.Chart.Wpf控件的动态调用

    最近需要在Wpf程序中显示曲线,感觉Sparrow.Chart.Wpf控件不错(http://sparrowtoolkit.codeplex.com/),完全开源的一个控件支持,可以通过nuget下载 ...

  8. 在WinForm应用程序中嵌入WPF控件

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

  9. 跟我一起学WPF(2):WPF控件基础

    WPF控件简介 通过上一篇XAML语言的介绍,我们知道,XAML是一个树形结构,同样,WPF控件作为构成整个XAML树的一部分,也是一个树形结构.我们看一个简单的例子. <Button.Cont ...

随机推荐

  1. 关于Topsort

    Long time no see. 拓扑排序 英文名称:Topological-sort 别称:toposort or  topsort 拓扑排序是干什么的呢 对一个有向无环图(Directed Ac ...

  2. struts2-token防止重复提交解决办法

    1.配置struts.xml全局防重复提交拦截器栈: <struts> <package name="module" extends="struts-d ...

  3. [tmux] Handle history in tmux sessions

    In this lesson, we'll look at how to manage your history between tmux sessions, and ensure that your ...

  4. css画电脑键盘

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. ios开发视频播放后台下载功能实现 :1,ios播放视频 ,包含基于AVPlayer播放器,2,实现下载,iOS后台下载(多任务同时下载,单任务下载,下载进度,下载百分比,文件大小,下载状态)(真机调试功能正常)

    ABBPlayerKit ios开发视频播放后台下载功能实现 : 代码下载地址:https://github.com/niexiaobo/ABBPlayerKit github资料学习和下载地址:ht ...

  6. 1069. The Black Hole of Numbers (20)【模拟】——PAT (Advanced Level) Practise

    题目信息 1069. The Black Hole of Numbers (20) 时间限制100 ms 内存限制65536 kB 代码长度限制16000 B For any 4-digit inte ...

  7. python property属性

    能够检查參数,一直没注意这个语言特性,忽略了非常多细节,感谢 vitrox class Person( object ): def __init__( self, name ): if not isi ...

  8. 日志报错Can't add self as subview

    #pragma mark- add 20151112 导航动画时间太短导致崩溃,重写UINavigationcontroller以下相关方法 - (id)navigationLock; ///< ...

  9. android通用適配器

    一.需求分析 在寻常的android开发过程中.ListView.GridView适配的编写是一件非常麻烦并且非常反复的事情,每次都须要考虑性能的优化.item的编写.获取网络图片时候信息的错乱等问题 ...

  10. scala 加载与保存xml文档

    package scala_enhance.xml import scala.xml.XML import scala.io.Source import jdk.internal.org.xml.sa ...