WPF DrawingContext似乎忽略了SnapToDevicePixels

时间:2011-05-16 13:25:23

标签: wpf graphics antialiasing

我正在DrawLine上直接拨打DrawingContext来绘制图表。由于我想避免任何抗锯齿功能,我试图将SnapToDevicePixels = true放在父UIElement上,但我仍然有反别名:

enter image description here

该项目是一个不是为WPF4编写的旧操作系统项目,但我将其重新定位到Framework4,这也是一个问题吗?

3 个答案:

答案 0 :(得分:11)

我发现this link他们基本上说你应该设置

ParentUIElement.SetValue(RenderOptions.EdgeModeProperty, EdgeMode.Aliased);

它对我有用,所以值得一试!

答案 1 :(得分:4)

SnapsToDevicePixels仅适用于元素边界框。您需要将Guidelines与DrawingContext一起使用。如果符合您的要求,您也可以指定VisualXSnappingGuidelinesVisualYSnappingGuidelines

答案 2 :(得分:3)

GuidelineSet旨在解决您的问题。

@Marat Khasanov建议您使用GuidelineSet并且您回复说它搞砸了您的代码。我也遇到了这个问题,所以我编写下面的代码用非丑陋的代码来解决这个问题。

注意:此方法即使在Viewbox

中也能正常工作
public static class SnapDrawingExtensions
{
    public static void DrawSnappedLinesBetweenPoints(this DrawingContext dc,
        Pen pen, double lineThickness, params Point[] points)
    {
        var guidelineSet = new GuidelineSet();
        foreach (var point in points)
        {
            guidelineSet.GuidelinesX.Add(point.X);
            guidelineSet.GuidelinesY.Add(point.Y);
        }
        var half = lineThickness / 2;
        points = points.Select(p => new Point(p.X + half, p.Y + half)).ToArray();
        dc.PushGuidelineSet(guidelineSet);
        for (var i = 0; i < points.Length - 1; i = i + 2)
        {
            dc.DrawLine(pen, points[i], points[i + 1]);
        }
        dc.Pop();
    }
}

调用OnRender中的方法并将行点传递给它。

protected override void OnRender(DrawingContext dc)
{
    // Draw four horizontal lines and one vertical line.
    // Notice that even the point X or Y is not an integer, the line is still snapped to device.
    dc.DrawSnappedLinesBetweenPoints(_pen, LineThickness,
        new Point(0, 0), new Point(320, 0),
        new Point(0, 40), new Point(320, 40),
        new Point(0, 80.5), new Point(320, 80.5),
        new Point(0, 119.7777), new Point(320, 119.7777),
        new Point(0, 0), new Point(0, 120));
}

以下是视图框中的渲染结果: snapped result