/
SimpleCircleAdorner.cs
114 lines (97 loc) · 4 KB
/
SimpleCircleAdorner.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// // Copyright (c) Microsoft. All rights reserved.
// // Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace DragDropObjects
{
public class SimpleCircleAdorner : Adorner
{
private readonly Rectangle _child;
private double _leftOffset;
private double _topOffset;
// Be sure to call the base class constructor.
public SimpleCircleAdorner(UIElement adornedElement)
: base(adornedElement)
{
var brush = new VisualBrush(adornedElement);
_child = new Rectangle
{
Width = adornedElement.RenderSize.Width,
Height = adornedElement.RenderSize.Height
};
var animation = new DoubleAnimation(0.3, 1, new Duration(TimeSpan.FromSeconds(1)))
{
AutoReverse = true,
RepeatBehavior = RepeatBehavior.Forever
};
brush.BeginAnimation(Brush.OpacityProperty, animation);
_child.Fill = brush;
}
protected override int VisualChildrenCount => 1;
public double LeftOffset
{
get { return _leftOffset; }
set
{
_leftOffset = value;
UpdatePosition();
}
}
public double TopOffset
{
get { return _topOffset; }
set
{
_topOffset = value;
UpdatePosition();
}
}
// A common way to implement an adorner's rendering behavior is to override the OnRender
// method, which is called by the layout subsystem as part of a rendering pass.
protected override void OnRender(DrawingContext drawingContext)
{
// Get a rectangle that represents the desired size of the rendered element
// after the rendering pass. This will be used to draw at the corners of the
// adorned element.
var adornedElementRect = new Rect(AdornedElement.DesiredSize);
// Some arbitrary drawing implements.
var renderBrush = new SolidColorBrush(Colors.Green) {Opacity = 0.2};
var renderPen = new Pen(new SolidColorBrush(Colors.Navy), 1.5);
const double renderRadius = 5.0;
// Just draw a circle at each corner.
drawingContext.DrawRectangle(renderBrush, renderPen, adornedElementRect);
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);
}
protected override Size MeasureOverride(Size constraint)
{
_child.Measure(constraint);
return _child.DesiredSize;
}
protected override Size ArrangeOverride(Size finalSize)
{
_child.Arrange(new Rect(finalSize));
return finalSize;
}
protected override Visual GetVisualChild(int index) => _child;
private void UpdatePosition()
{
var adornerLayer = Parent as AdornerLayer;
adornerLayer?.Update(AdornedElement);
}
public override GeneralTransform GetDesiredTransform(GeneralTransform transform)
{
var result = new GeneralTransformGroup();
result.Children.Add(base.GetDesiredTransform(transform));
result.Children.Add(new TranslateTransform(_leftOffset, _topOffset));
return result;
}
}
}