WPF Path исчезает в некотором размере - PullRequest
0 голосов
/ 11 февраля 2019

Я столкнулся с этой проблемой при масштабировании графика, который рисуется поверх ГИС-элемента управления Greatmap.Но простой эксперимент убеждает меня, что проблемы в WPF где-то глубже.

Рассмотрим простое приложение WPF:

Это MainWindow.xaml

<Grid>
    <StackPanel>
        <Slider ValueChanged="Size_Changed" Minimum="0" Maximum="300000"/>
        <TextBox x:Name="Value"></TextBox>
    </StackPanel>
    <Canvas>
        <Path x:Name="MyPath" Stroke="Black" StrokeThickness="2" />
    </Canvas>
</Grid>

И это его кодпозади

private void Size_Changed(object sender,
        RoutedPropertyChangedEventArgs<double> e)
    {
        if (MyPath == null) return;

        var g = new StreamGeometry();
        using (var s = g.Open())
        {
            var pointA = new Point(0, 200);

            s.BeginFigure(pointA, false, false);

            var pointB = new Point(e.NewValue, 200);

            s.PolyLineTo(new[] {pointB}, true, true);

            Value.Text = $"zoom = {e.NewValue:0.0} ;  pointA = {pointA.X:#,0} ; pointB = {pointB.X:#,0}";
        }

        g.Freeze();

        MyPath.Data = g;
    }

Пока я перетаскиваю ползунок от 0 до 249999, все в порядке.Я вижу линию на моем взгляде.Но в тот момент значение ползунка становится 250000 - строка исчезает.

Есть ли какие-либо ограничения в WPF?

Ответы [ 4 ]

0 голосов
/ 19 февраля 2019

Похоже, что это связано с проблемой, описанной в следующих Горизонтальные или вертикальные линии WPF, ограниченные 125 000 пикселей?

По-видимому, существует максимальная длина от ширины обводки до длиныСоотношение в WPF, относящееся к способу визуализации графики, которое может быть продиктовано графическим рендерингом.Если ширина хода изменяется, можно наблюдать следующее:

  • Если ширина хода равна 1: максимальная допустимая длина составляет 125 000
  • Если ширина хода равна 2: максимальная допустимая длина равна250 000
  • Если ширина хода равна 3: максимально допустимая длина составляет 375 000
0 голосов
/ 13 февраля 2019

Очень захватывающая проблема, наверное, это ошибка.Если вы измените точку A, как показано ниже:

var pointA = new Point(1, 200);

, тогда это будет работать ... :-)

0 голосов
/ 14 февраля 2019

По какой-то причине лежащие в основе алгоритмы (это может быть Direct2D или его предок) считают отношение StrokeThickness / Geometry экстента и решают, что штрих невидим в некоторой точке (1 против 125000).Это также несколько упомянуто здесь в этом другом вопросе: WPF DrawGeometry не рисует обводку .

Но штрих - это кисть, поэтому вы можете обмануть систему, используя эту кисть, например, в этом случае:

// use pen size instead of StrokeThickness
var geo = new GeometryDrawing(null, new Pen(Brushes.Black, 2), 
              new RectangleGeometry(new Rect(0, 0, e.NewValue, 1))); // use desired width for the geometry
var brush = new DrawingBrush(geo);
brush.Stretch = Stretch.None; // use this brush size, don't stretch to stroke thickness
brush.Freeze();
MyPath.Stroke = brush;

// choose a big number (more than desired thickness * 125000) to fool WPF or its friends
MyPath.StrokeThickness = 1000;
0 голосов
/ 11 февраля 2019

Я не вижу ограничений в WPF.Для меня это выглядит как ошибка WPF в рендеринге.

Я могу предложить только обходной путь, но я не знаю, почему это вызывает проблему после 250000 .Я не знаю, применим ли этот обходной путь к вашему реальному случаю.Идея состоит в том, чтобы использовать LayoutTransform для рисования горизонтальной линии:

private void Size_Changed(object sender, RoutedPropertyChangedEventArgs<double> e)
{
    if (MyPath == null) return;

    var g = new StreamGeometry();
    using (var s = g.Open())
    {
        var pointA = new Point(0, 200);

        s.BeginFigure(pointA, false, false);

        var pointB = new Point(1, 200);

        s.PolyLineTo(new[] { pointB }, true, true);

        MyPath.LayoutTransform = new ScaleTransform(e.NewValue, 1);

        Value.Text = $"zoom = {e.NewValue:0.0} ;  pointA = {pointA.X:#,0} ; pointB = {pointB.X:#,0}";
    }

    g.Freeze();

    MyPath.Data = g;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...