Textbox and Textblock won't line up

42 views Asked by At

I'm currently practicing xaml. I was going to make a simple menus with textbox and textblock.

When I drag textblock or textbox to the canvas, it is look ok. But it is way off after I run the program. I thought the reason is the Margin portion but after two hours, it turned out it is not.

What am I missing here? editing view after run view

<Page
    x:Class="newPrac.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:newPrac"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid>
        <ComboBox x:Name="comboBox" Margin="218,56,0,0" Width="111" Height="42">
            <ComboBoxItem Content="Noodle"/>
            <ComboBoxItem Content="Rice"/>
            <ComboBoxItem Content="Burger"/>
            <ComboBoxItem Content="Pizza"/>
        </ComboBox>
        <TextBlock x:Name="textCompany" Margin="57,110,1114,571" TextWrapping="Wrap" Text="2" FontSize="18"/>
        <TextBlock x:Name="textFrom" Margin="57,190,1127,486" TextWrapping="Wrap" Text="4" FontSize="18" />
        <TextBlock x:Name="textBlock" Margin="58,290,1136,388" TextWrapping="Wrap" Text="6" FontSize="18"/>
        
        <TextBox x:Name="textBox" Margin="41,55,1139,622" TextWrapping="Wrap" Text="1" Width="100"/>
        <TextBox x:Name="textBox1" Margin="229,129,951,547" TextWrapping="Wrap" Text="3" Width="100"/>
        <TextBox x:Name="txt" Margin="229,190,951,485" TextWrapping="Wrap" Text="5" Width="100"/>
        
        <TextBox x:Name="txtWho" Margin="217,290,963,385" TextWrapping="Wrap" Text="TextBox" Width="100"/>
    </Grid>
</Page>
2

There are 2 answers

2
Aleksandar On BEST ANSWER

Try defining your grid columns and rows and fit the individual control class objects in there instead of loosely dragging them - their alignment might be obstructed by their width and positons. Indexing starts at 0 and looks something like this:

<Grid>
    <Grid.ColumnDefinitions>
        <!--COLUMN DEFINITIONS (SET SIZE FOR EACH WITH = VALUE, AUTO OR *-->
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <!--ROW DEFINITIONS (SET SIZE FOR EACH WITH = VALUE, AUTO OR *-->
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
</Grid>

The rows and columns can be fitted with to specific widths and/or heights or can simply be denoted with Auto for automatic sizing depending on the containing control objects or * to fill in the rest of the space compared to the program window and definitons. The row and column for each control object can be set with Grid.Row="x" or Grid.Column="x" where x would be the row or column number (again, indexing starts at 0).

Furthermore, you could wrap the objects in a WrapPanel or StackPanel to treat them collectively rather than individually.

0
lidqy On

Using Margins for absolute positioning is something that some WYSIWYG designers do when you move your control with drag & drop, and it's really a bad habit, destroying all reasonable layout (I think Blend does it and the VS-XAML-designer "Cider" as well. Which is why most XAML "authors" prefer writing the markup manually).
What you are looking for seems an ordered and clean positioning in a WPF grid using Grid.RowDefinitions and Grid.ColumnDefinitions, along with HorizontalAlignment and VerticalAlignment for a more sublime alignment within the control's logical rect, and Margin to precisely and pixel-exact adjust relative distances between neighbouring elements in and all 4 ltrb directions. The following XAML might basically do the layout you seem to have intended in your first screenshot image.

<Page x:Class="newPrac.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:newPrac"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid>
        <Grid.Resources>
            <Style BasedOn="{StaticResource {x:Type TextBlock}}" TargetType="TextBlock">
                <Setter Property="TextWrapping" Value="Wrap" />
                <Setter Property="FontSize" Value="18" />
                <Setter Property="MinHeight" Value="22" />
                <Setter Property="Margin" Value="8,2,2,2" />
                <Setter Property="HorizontalAlignment" Value="Left" />
                <Setter Property="VerticalAlignment" Value="Center" />
            </Style>
            <Style BasedOn="{StaticResource {x:Type TextBox}}" TargetType="TextBox">
                <Setter Property="TextWrapping" Value="Wrap" />
                <Setter Property="Width" Value="100" />
                <Setter Property="MinHeight" Value="22" />
                <Setter Property="Margin" Value="8,2,2,2" />
                <Setter Property="HorizontalAlignment" Value="Left" />
                <Setter Property="VerticalAlignment" Value="Center" />
            </Style>
            <Style BasedOn="{StaticResource {x:Type ComboBox}}" TargetType="ComboBox">
                <Setter Property="Width" Value="111" />
                <Setter Property="MinHeight" Value="22" />
                <Setter Property="Margin" Value="8,2,2,2" />
                <Setter Property="HorizontalAlignment" Value="Left" />
                <Setter Property="VerticalAlignment" Value="Center" />
            </Style>
        </Grid.Resources>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <TextBox x:Name="textBox" Grid.Row="0" Grid.Column="0" Text="1" />
        <ComboBox x:Name="comboBox" Grid.Row="0" Grid.Column="1">
            <ComboBoxItem Content="Noodle" />
            <ComboBoxItem Content="Rice" />
            <ComboBoxItem Content="Burger" />
            <ComboBoxItem Content="Pizza" />
        </ComboBox>
        <TextBlock x:Name="textCompany" Grid.Row="1" Grid.Column="0" Text="2" />
        <TextBox x:Name="textBox1" Grid.Row="1" Grid.Column="1" Text="3" />
        <TextBlock x:Name="textFrom" Grid.Row="2" Grid.Column="0" Text="4" />
        <TextBox x:Name="txt" Grid.Row="2" Grid.Column="1" Text="5" />
        <TextBlock x:Name="textBlock" Grid.Row="3" Grid.Column="0" Text="6" />
        <TextBox x:Name="txtWho" Grid.Row="3" Grid.Column="1" Text="7" />
    </Grid>
</Page>

Note that I have put the styles that are common to all eleemnts of TextBox, TextBlock and ComboBox into un-keyed styles. This way you just have to adjust one setter and it applies to all controls of that type.