mli
mli

Reputation: 431

WPF Path disappears at some size

I have encountered this problem while scaling graph, which is drawn over GIS control Greatmap. But a simple experiment persuades me that problems is somewhere deeper in WPF.

Consider simple WPF application:

This is 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>

And this is its code behind

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;
    }

While I drag slider from 0 to 249999 it’s all right. I can see line on my view. But at the very moment slider’s value becomes 250000 – line disappears.

Is there any limitations in WPF ?

Upvotes: 20

Views: 1127

Answers (4)

TheMachinist
TheMachinist

Reputation: 338

This appears to be related to the issue described in the the following Horizontal or vertical WPF Lines limited to 125,000 pixels?

There appears to be a maximum length to stroke width to length ratio in WPF relating to how the graphics are rendered - which could be dictated by the graphics rendering. It the stroke width is varied the following can be observed:

  • If the stroke width is 1 : max length allowed is 125,000
  • If the stroke width is 2 : max length allowed is 250,000
  • If the stroke width is 3 : the max length allowed is 375,000

Upvotes: 1

Simon Mourier
Simon Mourier

Reputation: 139216

For some reason, the underlying algorithms (could be Direct2D or it's ancestor) considers the ratio StrokeThickness / Geometry extent and decides the stroke is invisible at some point (1 vs 125000). It's also somewhat mentioned here in this other question: WPF DrawGeometry does not draw stroke.

But the stroke is a brush, so you can trick the system like this, using a custom brush, for example in this case:

// 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;

Upvotes: 3

Chinh Nguyen
Chinh Nguyen

Reputation: 673

Very exciting issue, I guess it must be a bug. If you changed the pointA as below:

var pointA = new Point(1, 200);

then it would work ... :-)

Upvotes: 0

Rekshino
Rekshino

Reputation: 7325

I see no limitations in WPF. For me it looks like a WPF bug in rendering.

I can only offer a workaround, but I don't know why it causes the issue after 250000. I don't know whether this workaround applicable to your real case. The idea is to use LayoutTransform to draw a horizontal line:

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;
}

Upvotes: 0

Related Questions