开发者

WPF DrawingContext seems ignore SnapToDevicePixels

开发者 https://www.devze.com 2023-03-06 10:39 出处:网络
I\'m drawing a chart by direct calls to DrawLine on the DrawingContext. Since I want to avoid any anti aliasing fe开发者_如何学运维ature, I tryed to put the SnapToDevicePixels=true on the parent UIEle

I'm drawing a chart by direct calls to DrawLine on the DrawingContext. Since I want to avoid any anti aliasing fe开发者_如何学运维ature, I tryed to put the SnapToDevicePixels=true on the parent UIElement, but I still have anti-alias:

WPF DrawingContext seems ignore SnapToDevicePixels

The project was an old OS project not written for WPF4, but I retarget it to the Framework4, can this be an issue too ?


I found this link where they basically say you should set

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

It worked for me, so it might be worth a try!


SnapsToDevicePixels works only for element bounding box. You need to use Guidelines with DrawingContext. Also you can specify VisualXSnappingGuidelines and VisualYSnappingGuidelines if it fits to your requirements.


GuidelineSet is designed to resolve your problems.

@Marat Khasanov recommended you to use GuidelineSet and you replied that it messed up your code. I'm also suffering from this problem, so I write the code below to solve this problem with non-ugly code.

Notice: This method works even in a 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();
    }
}

Call the method in OnRender and pass line points to it.

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));
}

Here is the render result in a viewbox:

WPF DrawingContext seems ignore SnapToDevicePixels

0

精彩评论

暂无评论...
验证码 换一张
取 消