Как нарисовать N линий на дюйм? - PullRequest
0 голосов
/ 22 ноября 2010

мой код ниже должен отображать N строк на дюйм.вместо этого я получаю чуть больше N строк на дюйм.расстояние между линиями несколько меньше.Кроме того, изменение разрешения экрана приводит к изменению расстояния между строками.Кто-нибудь знает, как справиться с этим?


using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace MyApp
{
    class MyControl : Control
    {
        private readonly ContainerVisual container = new ContainerVisual();
        private readonly DrawingVisual drawing = new DrawingVisual();

        private void RenderDrawing()
        {
            var s = PresentationSource.FromVisual(this);
            var dpiX = 96 * s.CompositionTarget.TransformToDevice.M11;
            var dpiY = 96 * s.CompositionTarget.TransformToDevice.M22;

            double N = 1;

            using (var c = drawing.RenderOpen())
            {
                var p = new Pen(new SolidColorBrush(Colors.Black), 1);

                for (int i = 0; i < 10; i++)
                {
                    var x = i * dpiX / N;
                    c.DrawLine(p, new Point(x, 0), new Point(x, 100));
                }
            }
        }

        protected override Size ArrangeOverride(Size s)
        {
            RenderDrawing();
            return s;
        }

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

        protected override Size MeasureOverride(Size s)
        {
            return new Size();
        }

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

        public MyControl()
        {
            container.Children.Add(drawing);
            AddVisualChild(container);
        }
    }
}

Ответы [ 2 ]

1 голос
/ 23 ноября 2010

В этой статье обсуждается та же проблема: Проблемы с WPF DPI нет решения этой проблемы, кроме как попросить пользователя установить правильные настройки DPI, соответствующие физическому DPI экрана. Обходной путь, который я нашел, который делает жизнь немного проще, - это использовать масштабирование уровня приложений WPF, как описано здесь: http://www.odewit.net/ArticleContent.aspx?id=WpfDpiScaling&lang=en&format=html

0 голосов
/ 22 ноября 2010

Не уверен, что это достигнет того, что вы ищете, но это должно помочь, если проблема связана с округлением.Как я уже говорил в комментариях, ваш код выглядит в основном правильно, я думаю, что это проблема округления при вычислении dpi.Поскольку вы хотите визуализировать на основе 96 точек на дюйм, вычислите координаты на основе 96 точек на дюйм, а затем конвертируйте точки в ваше устройство.Я написал это для большей ясности, вы можете использовать один массив точек и просто помнить, что i - это начальная точка, а i+1 - это конечная точка, и тогда вам потребуется всего лишь один вызов для преобразования точек.

    private void RenderDrawing()
    {
        var s = PresentationSource.FromVisual(this);
        var dpiX = 96;

        int numberOfLines = 10;
        double N = 1;
        double spacing = dpiX / N;

        var startPoints = new Point[numberOfLines]();
        var endPoints = new Point[numberOfLines]();
        for (int i = 0; i < numberOfLines; i++)
        {
            var x = i * spacing;
            startPoints[i] = new Point(x, 0);
            endPoints[i] = new Point(x, 100);                 
        }
        s.CompositionTarget.TransformToDevice.Transform(startPoints);
        s.CompositionTarget.TransformToDevice.Transform(endPoints);

        using (var c = drawing.RenderOpen())
        {
            using (var p = new Pen(new SolidColorBrush(Colors.Black), 1))
            {
                 for(int i=0; i < numberOfLines; i++)
                 {
                    c.DrawLine(p, startPoints[i], endPoints[i]);
                 }
            }
        }
    }
...