Attempting to animate a control by modifying its margins, I realized that I might not fully understand the effects of the different alignment options on negative margins. To better explain my question, I created an example containing two TextBlock controls each surrounded by a Border.
As shown below, I attempt to give the first TextBlock _TextBlock1
(blue) - which has a vertical alignment of Top
- a top margin of -20 so that its bottom edge will sit immediately on top of its border _Border1
. This produces the desired result. I then attempt to achieve the same effect on TextBlock _TextBlock2
(orange), which is identical to _TextBlock1
except for its vertical alignment of Center
. Since this TextBlock is centered vertically, I apply a top margin of -40, which from my understanding should produce the same result (20 pixels to move its top edge to the top edge of the border _Border2
and another 20 pixels to bring it fully above the border).
As shown on the image below - taken from the designer view in Visual Studio - I seem to be missing something about how the margins affect the placement of these controls given their vertical alignment type. Could somebody explain to me how I should be interpreting the interaction between margins and alignment types (as related to this example)? Also, how can I modify the margins on _TextBlock2
to produce the same results as _TextBlock1
?
<Window x:Class="Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Test"
Height="350" Width="525">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="60"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="60"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border
x:Name="_Border1"
Grid.Row="1"
Grid.Column="1"
BorderBrush="Black"
BorderThickness="1">
<TextBlock
Margin="0 -20 0 0"
x:Name="_TextBlock1"
Background="DodgerBlue"
VerticalAlignment="Top"
Height="20"/>
</Border>
<Border
x:Name="_Border2"
Grid.Row="1"
Grid.Column="2"
BorderBrush="Black"
BorderThickness="1">
<TextBlock
Margin="0 -40 0 0"
x:Name="_TextBlock2"
Background="Orange"
VerticalAlignment="Center"
Height="20"/>
</Border>
</Grid>
</Window>
Margins do not 'move' an element. Margins effectively grow or shrink the size of an element's layout rectangle, which is provided by its parent. Alignment controls how an element positions itself within its layout rectangle.
Initially, the orange block has its parent's entire area available for positioning, so its layout rectangle starts with a height of 60
. Normally, adding (positive) margins shrinks the portion of the layout rectangle available to position an element. But a top margin of -40
effectively grows the orange block's layout rectangle so it has a height of 60 - (-40) = 100
. Let's define the top-left corner of our effective layout rectangle as being (0, 0)
. Relative to this, the parent border's top-left corner is (0, 40)
.
The orange block has a height of 20
, and it has 100
units of vertical space in which to center itself. (100 - 20) / 2 = 40
, so the block gets 40
units of vertical space above it and below it. This puts the orange block's top-left corner at (0, 40)
, right along with its parent.
You can modify your _TextBlock2 as below to obtain required behaviour:
<TextBlock
Margin="0 -80 0 0"
x:Name="_TextBlock2"
Background="Orange"
VerticalAlignment="Center"
Height="20"/>
To have a better understanding regarding margins and padding go here.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.