Я рисую диаграмму прямым вызовом DrawLine на DrawingContext. Поскольку я хочу избежать какой-либо функции сглаживания, я попытался установить SnapToDevicePixels = true в родительский UIElement, но у меня все еще есть сглаживание:

enter image description here

Это был старый проект ОС, не написанный для WPF4, но я перенастроил его на Framework4, может ли это быть проблемой?

18
Felice Pollano 16 Май 2011 в 17:25

3 ответа

Лучший ответ

SnapsToDevicePixels работает только для ограничивающего прямоугольника элемента. Вам необходимо использовать рекомендации с DrawingContext. Также вы можете указать VisualXSnappingGuidelines и < a href = "http://msdn.microsoft.com/en-us/library/system.windows.media.visual.visualxsnappingguidelines.aspx" rel = "noreferrer"> VisualYSnappingGuidelines , если он соответствует вашим требованиям.

5
Marat Khasanov 16 Май 2011 в 17:51
Ваше предложение действительно работает. Чтобы создать правильные ориентиры, я должен учитывать все координаты, которые я буду рисовать, и даже добавить половину ширины пера. Это создает действительно беспорядочный код (а писать такие вещи - кошмар). Разве нет каких-то ярлыков?
 – 
Felice Pollano
16 Май 2011 в 19:38
Поллано: Ничего не нашел :( Даже классы фреймворка используют примитивное решение «new GuidelineSet -> GuidelineSet.Add -> PushGuidelineSet». Например, взгляните на метод OnRender класса TickBar.
 – 
Marat Khasanov
17 Май 2011 в 11:26
Спасибо за ответ. Собственно смотрю на результат, не знаю, лучше ли он с анти-псевдонимом ...
 – 
Felice Pollano
17 Май 2011 в 11:28

Я нашел эту ссылку, где они в основном говорят, что вы должны установить

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

У меня это сработало, так что, возможно, стоит попробовать!

17
Markus Hütter 4 Ноя 2011 в 19:40

GuidelineSet предназначен для решения ваших проблем.

@ Марат Хасанов рекомендовал вам использовать 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

3
walterlv 19 Июл 2017 в 14:44