简体   繁体   中英

WPF - Effects of “Center” vertical alignment on negative margins

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM