StreamGeometry结合

我有复杂的StreamGeometry ,我想剪辑它。 不幸的是,看起来StreamGeometry不支持组合。

这是一个测试。

XAML:

  

码:

 var clip = new RectangleGeometry(new Rect(50, 50, 10, 10)); var rect = new RectangleGeometry(new Rect(0, 0, 100, 100)); var stream = new StreamGeometry(); using (var geometry = stream.Open()) { geometry.BeginFigure(new Point(0, 0), false, true); geometry.LineTo(new Point(0, 100), true, false); geometry.LineTo(new Point(100, 100), true, false); geometry.LineTo(new Point(100, 0), true, false); } //path.Data = rect; //path.Data = stream; //path.Data = clip; //path.Data = Geometry.Combine(rect, clip, GeometryCombineMode.Intersect, null); //path.Data = Geometry.Combine(stream, clip, GeometryCombineMode.Intersect, null); 

取消注释第一行(显示rect )或第二行(显示stream )会产生相同的视觉效果:

取消注释第三行(显示clip )或第四行(显示cliprect交集)将产生:

取消注释最后一行(显示clipgeometry交集)会产生空白屏幕。

我的问题是: 如何组合(剪辑)StreamGeometry

我知道有UIElement.Clip ,但是:

 // blank screen path.Data = stream; path.Clip = clip; // blank screen as well path.Data = stream; path.Clip = clip; 

解决方案很简单: 不要使用StreamGeometry

例如,这将起作用(改为使用PathGeometry ):

 var clip = new RectangleGeometry(new Rect(50, 50, 10, 10)); var geometry = new PathGeometry(new[] { new PathFigure(new Point(0, 0), new[] { new LineSegment(new Point(0, 100), true), new LineSegment(new Point(100, 100), true), new LineSegment(new Point(100, 0), true), }, true) }); path.Data = Geometry.Combine(clip, geometry, GeometryCombineMode.Intersect, null); 

结果:

很重要!

它看起来像UIElement.Clip仍然呈现不可见的部分(mayhap只使用StreamGeometry )! 永远不要用它! 分配之前剪辑几何体。

你绝对可以组合StreamGeometry对象。 为此,您需要使用CombinedGeometry对象。 这是一个用于绘制带孔的多边形的简单扩展方法:

 public static void DrawPolygon(this DrawingContext context, Brush brush, Pen pen, IEnumerable exteriorRing, IEnumerable> interiorRings = null) { StreamGeometry geo = new StreamGeometry(); Geometry finalGeometry = geo; using (StreamGeometryContext ctxExterior = geo.Open()) { ctxExterior.BeginFigure(exteriorRing.First(), (brush != null), true); ctxExterior.PolyLineTo(exteriorRing.Skip(1).ToArray(), (pen != null), false); if (interiorRings != null) { foreach (var ring in interiorRings) { var interiorGeometry = new StreamGeometry(); using (var ctxInterior = interiorGeometry.Open()) { ctxInterior.BeginFigure(ring.First(), true, true); ctxInterior.PolyLineTo(ring.Skip(1).ToArray(), (pen != null), false); } finalGeometry = new CombinedGeometry(GeometryCombineMode.Exclude, finalGeometry, interiorGeometry); } } } context.DrawGeometry(brush, pen, finalGeometry); }