WPF Line.Measure seems to give incorrect results

F

Fred Mellender

I have a vertical line going from (20,0) to (20,-200):


CODE:
Line foo = new Line();
foo.X1 = 20;
foo.Y1 = 0;
foo.X2 = 20;
foo.Y2 = -200;

foo.StrokeThickness = 4;
foo.Stroke = Brushes.Black;

foo.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
Size fooSize = foo.DesiredSize;
bool valid = foo.IsMeasureValid;

RESULTS:
valid is true and
fooSize is:
fooSize.height = 0.0;
fooSize.width = 22.0 (twenty-two)

I was expecting height = 200, width = 4.

Can someone explain how else I can get the bounding box of a line (or other
UIElement), and what DesiredSize is returning?

I am trying to work in world coordinates and need the various bounding boxes
of the UIElements
that I will add to a canvas, so that I can scale the entire canvas to a
containing panel, (via a transform).
It all works well if I calculate the bounding boxes myself but I wanted
something more general.
 
N

not_a_commie

The Line object will have an ActualWidth, ActualHeight members that
give the sizes after Measure and Arrange have been called. And have
you considered doing your scaling with matrix transforms?
 
F

Fred Mellender

I wanted to calculate the matrix transforms before Measure and Arrange have
been called. I am trying to scale
the panel, world, (and thus its contents) based on examining all its
childrens' width/height and position.

The code I am using is:

foreach (UIElement s in world.Children)
{
double top = 0, bottom = 0, left = 0, right = 0;

s.Measure(new Size(double.PositiveInfinity,
double.PositiveInfinity));
Size elementSize = s.DesiredSize;

Line line = s as Line;

if (line != null)
{
top = Math.Max(line.Y1, line.Y2);
left = Math.Min(line.X1, line.X2);
bottom = Math.Min(line.Y1, line.Y2);
right = Math.Max(line.X1, line.X2);

//bottom = top - elementSize.Height;
//right = left + elementSize.Width;
}

else ....... //etc for other objects.....

maxX = Math.Max(right, maxX);
maxY = Math.Max(top, maxY);
minX = Math.Min(left, minX);
minY = Math.Min(bottom, minY);
}

double maxWidth = maxX - minX;
double maxHeight = maxY - minY;

world.Measure(new Size(double.PositiveInfinity,
double.PositiveInfinity));
Size size = world.DesiredSize;

double scaleX = graphicPanel.ActualWidth / maxWidth;
double scaleY = -graphicPanel.ActualHeight / maxHeight;

ScaleTransform transS = new ScaleTransform(scaleX, scaleY);
ScaleTransform transS = new ScaleTransform(scaleX, scaleY);
TranslateTransform transT = //since we
translate after scaling, we must scale the translate first
new TranslateTransform(-minX * Math.Abs(scaleX), maxY *
Math.Abs(scaleY));

TransformGroup group = new TransformGroup();
group.Children.Add(transS);
group.Children.Add(transT);

graphicPanel.RenderTransform = group;

The commented lines are what I wanted to use for bottom/right.

I do not understand why the elementSize.Height/Width are not accurate, or
what the
values they are set to, mean.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top