Как я могу создать скошенные углы на границе в WPF? - PullRequest
2 голосов
/ 11 апреля 2011

Я пытаюсь сделать простое рисование в подклассе декоратора, подобное тому, что они делают здесь ...

Как нарисовать границу с прямоугольными углами в wpf?

... за исключением толщины границы в один пиксель вместо двух, которые они там используют. Однако, независимо от того, что я делаю, WPF решает, что ему нужно выполнить «сглаживание» (например, вместо рендеринга однопиксельной линии, он рендерит двухпиксельную линию с каждой «половиной» около 50% непрозрачности). Другими словами, он пытается сглаживать рисунок. Я не хочу сглаживание рисунка. Я хочу сказать, что если я нарисую линию от 0,0 до 10,0, я получу линию шириной в один пиксель длиной ровно 10 пикселей без сглаживания.

Теперь я знаю, что WPF делает это, но я подумал, что именно поэтому они представили SnapsToDevicePixels и UseLayoutRounding, оба из которых я установил в True на XAML. Я также проверяю, что числа, которые я использую, являются действительными целыми числами, а не дробными числами, но тем не менее я не получаю красивые четкие линии шириной в один пиксель, на которые я надеюсь.

Помощь !!!

Mark

Ответы [ 2 ]

2 голосов
/ 12 апреля 2011

А-а-а-а .... понял! WPF считает строку от 0,0 до 10,0 буквально на этой логической строке, а не на строке пикселей, как в GDI. Чтобы лучше объяснить, представьте, что координаты в WPF являются репрезентативными для линий, нарисованных на листе миллиметровки, тогда как пиксели - это квадраты, из которых состоят эти линии (при условии 96 точек на дюйм. Вам нужно будет соответствующим образом отрегулировать, если они разные .)

Итак ... чтобы рисунок мог ссылаться на местоположения пикселей, нам нужно сместить чертеж от самих линий, чтобы он был центром пикселей (квадратов на миллиметровке), чтобы мы сместили весь рисунок на 0,5, 0,5 (опять же, при допущении DPI 96)

Так что, если это настройка 96 DPI, простое добавление этого в метод OnRender работает как чудо ...

drawingContext.PushTransform(new TranslateTransform(.5, .5));

Надеюсь, это поможет другим!

M

1 голос
/ 12 апреля 2011

Посмотрите на эту статью: Нарисуйте линии точно на пикселях физического устройства

UPD

Некоторые ценные цитаты из ссылки:

Причина, по которой линии выглядят размытыми, заключается в том, что наши точки являются центральными точками линий, а не краями.При ширине пера 1 края рисуются точно между двумя пикселями.

Первый подход заключается в округлении каждой точки до целочисленного значения (привязка к логическому пикселю) и присвоении ей смещения, равного половине ширины пера.,Это гарантирует, что края линии совпадают с логическими пикселями.

К счастью, разработчики milcore (MIL расшифровывается как слой интеграции медиа, то есть механизм рендеринга WPF) дают нам возможность направлять механизм рендеринга для точного выравнивания логических координат по пикселям физического устройства.Для этого нам нужно создать GuidelineSet

protected override void OnRender(DrawingContext drawingContext)
{
    Pen pen = new Pen(Brushes.Black, 1);
    Rect rect = new Rect(20,20, 50, 60);

    double halfPenWidth = pen.Thickness / 2;

    // Create a guidelines set
    GuidelineSet guidelines = new GuidelineSet();
    guidelines.GuidelinesX.Add(rect.Left + halfPenWidth);
    guidelines.GuidelinesX.Add(rect.Right + halfPenWidth);
    guidelines.GuidelinesY.Add(rect.Top + halfPenWidth);
    guidelines.GuidelinesY.Add(rect.Bottom + halfPenWidth);

    drawingContext.PushGuidelineSet(guidelines);
    drawingContext.DrawRectangle(null, pen, rect);
    drawingContext.Pop();
}
...