Reputation: 431
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
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:
Upvotes: 1
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
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
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