Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Path disappears at some size

Tags:

c#

wpf

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 ?

like image 775
mli Avatar asked Feb 11 '19 10:02

mli


2 Answers

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;
like image 82
Simon Mourier Avatar answered Oct 26 '22 23:10

Simon Mourier


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
like image 1
TheMachinist Avatar answered Oct 26 '22 23:10

TheMachinist