I'm getting close to the understanding of the positioning of the System.Windows.Controls.UserControl
objects:
By default, they don't have X or Y coordinates, relative to their container, but there is the possibility to add some, using so-called "Attached Properties".
A typical example of such attached properties are Canvas.Left
and Canvas.Top
, which mean that, in case the container of the UserControl
is a Canvas
, then the following happens with (supposingly) its upper left point (pseudo-code):
UserControl_UpperLeft_Point.X = Canvas.Left
UserControl_UpperLeft_Point.Y = Canvas.Top
Now what I'd like to know:
Is my idea correct? Is it indeed the upper left corner which is used?
What if I want to modify this behaviour, let's say into:
int left_Margin = 100;
int top_Margin = 200;
UserControl_UpperLeft_Point.X = Canvas.Left / 2 + left_Margin;
UserControl_UpperLeft_Point.Y = Canvas.Top * 2 + top_Margin;
What if I want to position my UserControl
, based on the upper right corner or even the center?
Is my idea correct? Is it indeed the upper left corner which is used?
It is effectively the upper left corner in this case, but actually each of the sides are aligned. Furthermore, the control is aligned by the Canvas
, it does not have internal X or Y coordinates that are set. They are given by the attached properties which are sepcific to the Canvas
, no other panel. The Canvas
internally calculates a rectangle where it draws the UserControl
.
Gets or sets a value that represents the distance between the left side of an element and the left side of its parent Canvas.
Gets or sets a value that represents the distance between the top of an element and the top of its parent Canvas.
It is also important to note, that there is a priority for the attached properties.
If you specify them, the attached properties Canvas.Top or Canvas.Left take priority over Canvas.Bottom or Canvas.Right.
What if I want to modify this behaviour, let's say into: [...]
You would still have to assign the attached properties, but calculate the expression before.
Binding
or MultiBinding
with a custom value converter that evaluates an expression that is bound or passed as converter parameter or with a specialized value converter to calculate a specific term.Canvas
attached properties.What if I want to position my UserControl, based on the upper right corner
Set the Canvas.Top
and Canvas.Right
attached properties instead.
<Canvas>
<local:MyUserControl Canvas.Top="0" Canvas.Right="0" Width="50" Height="80"/>
</Canvas>
[...] or even the center?
A Canvas
is used for absolute positioning. If you want to center controls, a Grid
might be the better choice. If you still want to use a Canvas
and it is fixed size, just calculate the center coordinates yourself and set the attached properties accordingly. If it is resizeable and the position of the UserControl
position needs to be responsive to that, you could do one of these.
Put a Grid
around the Canvas
and put the UserControl
after it. It will appear on top of the Canvas
and will be centered automatically, even on resizing.
Grid>
<Canvas>
<Rectangle Canvas.Top="80" Canvas.Left="20" Fill="Black" Width="50" Height="50"/>
<Rectangle Canvas.Top="300" Canvas.Left="230" Fill="Black" Width="100" Height="80"/>
</Canvas>
<local:MyUserControl Width="50" Height="80"/>
</Grid>
Implement a custom behavior or complicated bindings with converter using the bound ActualSize
of the Canvas
to set the attached properties, which I do not recommend.
I think for your last question it is more useful to ask why you need this behavior, what you want to achieve. Often there is a much simpler and more suitable solution.