Reputation: 27
i do have the following Code:
private static void AddElements(Canvas canvas)
{
double canvasHeight = canvas.Height;
double canvasWidth = canvas.Width;
double y0 = canvasHeight / 2;
double x0 = canvasWidth / 2;
// Defining the new Coordinate-Point (0,0) to mid auf Canvas
TranslateTransform tt = new TranslateTransform(x0, y0);
Line line1 = new Line();
line1.X1 = -350;
line1.Y1 = 0;
line1.X2 = 350;
line1.Y2 = 0;
line1.Stroke = Brushes.Black;
line1.StrokeThickness = 2.0;
line1.RenderTransform = tt;
canvas.Children.Add(line1);
Line line2 = new Line();
line2.X1 = 0;
line2.Y1 = -350;
line2.X2 = 0;
line2.Y2 = 350;
line2.Stroke = Brushes.Black;
line2.StrokeThickness = 2.0;
line2.RenderTransform = tt;
canvas.Children.Add(line2);
Label lblN = new Label();
lblN.Width = 50;
lblN.Background = Brushes.Red;
lblN.Margin = new System.Windows.Thickness(0, -350, 0, 0);
lblN.Content = $"N";
lblN.HorizontalContentAlignment = System.Windows.HorizontalAlignment.Center;
lblN.VerticalContentAlignment = System.Windows.VerticalAlignment.Center;
lblN.RenderTransform = tt;
lblN.Padding = new System.Windows.Thickness(0);
lblN.BorderBrush = Brushes.Black;
lblN.BorderThickness = new System.Windows.Thickness(2.0);
lblN.RenderTransform = tt;
canvas.Children.Add(lblN);
Label lblS = new Label();
lblS.Width = 50;
lblS.Background = Brushes.Red;
lblS.Margin = new System.Windows.Thickness(0, 350, 0, 0);
lblS.Content = $"S";
lblS.HorizontalContentAlignment = System.Windows.HorizontalAlignment.Center;
lblS.VerticalContentAlignment = System.Windows.VerticalAlignment.Center;
lblS.RenderTransform = tt;
lblS.Padding = new System.Windows.Thickness(0);
lblS.BorderBrush = Brushes.Black;
lblS.BorderThickness = new System.Windows.Thickness(2.0);
lblS.RenderTransform = tt;
canvas.Children.Add(lblS);
}
this method is called on an Menu-Eventhandler and it shows an coordinate system with (0,0) in the mid of the canvas. It should show a label with "N" at the top and a label with "S" at the bottom.
But i shows the attached image
Does anyone know, why lblN looks different than lblS ?
best regards
Volkhard
=============
if i set the height of both Label-Objects to 15
lblN.Height=15
:
lblS.Height=15
i get the following:
i expected the lblN to be more upper on the y-coordinate.
Upvotes: -1
Views: 204
Reputation: 6766
Through a bit of testing, I can definitely say that it's the lblN.Margin = new System.Windows.Thickness(0, -350, 0, 0);
that's causing the problem. Apparently, when you give a Label
a negative margin like that, it will move upwards only as far is it's Height
, and then it will start expanding instead of just continuing to move. So you end up with a Label
that's 350 tall. We could try to figure out why that is, but really, that would be missing the point.
Admittedly, I don't have any direct documentation to back up the following statement this, but from years of experience in WPF I feel I can say:
Margin
is intended to be used to give space between elements in a dynamic layout, not to give an element an absolute position.
This behavior of the Label
seems to strengthen the idea that using Margin
in this way was not something that was planed for by the designers.
Canvas
has tools for giving an element a set position, yet nowhere do you use Canvas
's SetLeft
, SetTop
, SetRight
, or SetBottom
. Take a look at the example on MSDN. You shouldn't need to use a TranslateTransform
or set Margin
at all. Instead, you should calculate where you want the element to be and use one of the above four listed methods to assign that position.
Don't use canvas.Height
and canvas.Width
, use canvas.ActualHeight
and canvas.ActualWidth
instead. The first pair only work if you are explicitly setting the size of the Canvas
(which it seems you are). But in a senario where the Canvas
is dynamically sized, the first pair will be NaN
. The second pair always return the actual size that the Canvas
is.
This doesn't make a difference in your current use case, but it might later on. If you're doing calculations based on the actual size of an element (as opposed to the size you might want it to be), always use ActualHeight
and ActualWidth
.
Upvotes: 0