Forcing drawingContext lines to snap to pixel boundaries

c#, wpf

Solution

You may draw the lines into a derived DrawingVisual that has the protected VisualEdgeMode property set to `EdgeMode.Aliased`:

public class MyDrawingVisual : DrawingVisual
{
    public MyDrawingVisual()
    {
        VisualEdgeMode = EdgeMode.Aliased;
    }
}

public class DrawingComponent : FrameworkElement
{
    private DrawingVisual visual = new MyDrawingVisual();

    public DrawingComponent()
    {
        AddVisualChild(visual);

        using (DrawingContext dc = visual.RenderOpen())
        {
            dc.DrawLine(new Pen(Brushes.Black, 1d), new Point(100, 100), new Point(100, 200));
            dc.DrawLine(new Pen(Brushes.Black, 1d), new Point(105.5, 100), new Point(105.5, 200));
            dc.DrawLine(new Pen(Brushes.Black, 1d), new Point(112, 100), new Point(112, 200));
        }
    }

    protected override int VisualChildrenCount
    {
        get { return 1; }
    }

    protected override Visual GetVisualChild(int index)
    {
        return visual;
    }
}

Strange enough, but calling `RenderOptions.SetEdgeMode(visual, EdgeMode.Aliased)` on a non-derived DrawingVisual doesn't do the job.

Problem

I'm drawing a graph in a WPF application, but lines drawn using `drawingContext.DrawLine(...)` are drawn to sub-pixel boundaries. I'm able to get them to look nice by creating `Line` objects, but I don't want to create tens of thousands of those every time the visual is invalidated. How can I force them to fit to pixels?

Original source