我有复杂的StreamGeometry
,我想剪辑它。不幸的是,看起来StreamGeometry
不支持合并。
这是一个测试。
的Xaml:
<Path x:Name="path" Stroke="Red"/>
代码:
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
)或第四行(显示clip
和rect
的交集)将产生:
取消注释最后一行(显示clip
和geometry
的交集)会产生空白屏幕。
我的问题是:如何组合(剪辑)StreamGeometry ?
我知道有UIElement.Clip
,但是:
// blank screen
path.Data = stream;
path.Clip = clip;
// blank screen as well
path.Data = stream;
path.Clip = clip;
答案 0 :(得分:1)
解决方案很简单:不要使用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
)!永远不要用它!剪辑几何之前分配它。
答案 1 :(得分:1)
您绝对可以合并StreamGeometry
个对象。为此,您希望使用CombinedGeometry
对象。这是一个简单的扩展方法,用于绘制带孔的多边形:
public static void DrawPolygon(this DrawingContext context, Brush brush, Pen pen, IEnumerable<Point> exteriorRing, IEnumerable<IEnumerable<Point>> 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);
}