Reputation: 33252
I'm drawing a chart by direct calls to DrawLine
on the DrawingContext
. Since I want to avoid any anti aliasing feature, I tryed to put the SnapToDevicePixels=true on the parent UIElement, but I still have anti-alias:
The project was an old OS project not written for WPF4, but I retarget it to the Framework4, can this be an issue too ?
Upvotes: 18
Views: 4816
Reputation: 2376
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:
Upvotes: 3
Reputation: 7906
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!
Upvotes: 17
Reputation: 3848
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.
Upvotes: 4