为Polygon实现自定义Adorner:顶点装饰器适配方法求助
为Polygon顶点添加Adorner的完整实现方案
我完全懂你现在的困扰——官方文档的Adorner示例是针对普通元素的四个角,要套用到Polygon的每个顶点上确实有点绕。我给你把代码改好,直接就能用,还会讲清楚关键改动点。
第一步:修改Adorner类,适配Polygon顶点
原来的示例只画元素的四个边角,我们需要改成遍历Polygon的所有顶点来绘制Adorner:
public class PolygonVertexAdorner : Adorner { private readonly Polygon _adornedPolygon; private readonly SolidColorBrush _fillBrush; private readonly Pen _borderPen; private const double AdornerRadius = 5.0; // 构造函数确保传入的是Polygon类型 public PolygonVertexAdorner(UIElement adornedElement) : base(adornedElement) { _adornedPolygon = adornedElement as Polygon; if (_adornedPolygon == null) throw new ArgumentException("要添加Adorner的元素必须是Polygon类型"); // 自定义Adorner的样式,你可以按需调整颜色、透明度 _fillBrush = new SolidColorBrush(Colors.Green) { Opacity = 0.2 }; _borderPen = new Pen(new SolidColorBrush(Colors.Navy), 1.5); } protected override void OnRender(DrawingContext drawingContext) { base.OnRender(drawingContext); // 空值判断,避免NullReferenceException if (_adornedPolygon?.Points == null || _adornedPolygon.Points.Count == 0) return; // 获取坐标转换:把Polygon的局部顶点坐标转成Adorner坐标系下的位置 Transform transform = _adornedPolygon.TransformToVisual(this); // 遍历每个顶点,绘制圆形Adorner foreach (Point vertex in _adornedPolygon.Points) { Point transformedPoint = transform.Transform(vertex); drawingContext.DrawEllipse(_fillBrush, _borderPen, transformedPoint, AdornerRadius, AdornerRadius); } } }
第二步:修改你的Polygon绘制代码,添加Adorner
在你原来的drawPolygon方法里,最后加上添加Adorner的逻辑,确保Polygon创建后立刻带上顶点标记:
Polygon myPolygon; private Polygon drawPolygon() { //Add the Polygon Element myPolygon = new Polygon(); // Appearance myPolygon.Stroke = System.Windows.Media.Brushes.LightCoral; // Disabled for hit testing on border only. //myPolygon.Fill = System.Windows.Media.Brushes.Transparent; myPolygon.StrokeThickness = 6; // Alignment myPolygon.HorizontalAlignment = HorizontalAlignment.Left; myPolygon.VerticalAlignment = VerticalAlignment.Center; // Point Array for polyline. // This will come from an XML file. Point[] polylinePoints = { // START: @ TOP LEFT new Point(200.0F, 200.0F), // 1ST LINE: TOP RIGHT new Point(400.0F, 200.0F), // 2ND LINE: BOMTTOM RIGHT new Point(400.0F, 400.0F), // 3RD LINE: BOTTOM LEFT new Point(200.0F, 400.0F), // END: @ TOP LEFT //Not Required to close the Polygon... //new Point(200.0F, 200.0F), }; // Load from Point[Array] polylinePoints. PointCollection myPointCollection = new PointCollection(polylinePoints); //myPointCollection.Add(Point1); // Add from PointCollection myPointCollection myPolygon.Points = myPointCollection; // 关键:给当前Polygon添加顶点Adorner AttachVertexAdornerToPolygon(myPolygon); return myPolygon; } // 封装添加Adorner的方法,复用性更强 private void AttachVertexAdornerToPolygon(Polygon polygon) { // 获取元素所在的AdornerLayer AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(polygon); if (adornerLayer != null) { // 创建并添加自定义Adorner var vertexAdorner = new PolygonVertexAdorner(polygon); adornerLayer.Add(vertexAdorner); } }
关键改动说明
- 针对性适配Polygon:新的Adorner类会先验证传入的元素是Polygon,避免类型错误。
- 坐标转换:用
TransformToVisual把Polygon的局部顶点坐标转换成Adorner坐标系下的位置,确保Adorner精准出现在顶点上(就算Polygon有布局偏移也没问题)。 - 空值安全:添加了多层空值判断,防止运行时抛出空引用异常。
- 可复用性:把添加Adorner的逻辑封装成单独方法,以后给其他Polygon加Adorner直接调用就行。
内容的提问来源于stack exchange,提问作者suchislife801
相关产品推荐
相关产品推荐

