iamIcarus
iamIcarus

Reputation: 1438

WPF Window resize "eats" controls width

I have an issue im struggling a day now. Im trying to center some controls into a Grid layout. I have 2 columns and i want half of the controls centered ad the 1st column and other half to the second column

When the window resize some of them get "eaten" on the edges , and i wasent able to identify the issue

enter image description here

Can anyone spot the issue?

  <Grid Margin="0,2,0,-2">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>


//....... 
 <ComboBox x:Name="optMenuLeft"  Margin="0,271,0,0" VerticalAlignment="Top" Height="26" HorizontalAlignment="Center" Width="170" Grid.RowSpan="2"  />
 <Label Content="Menu" Margin="141,271,390,0" VerticalAlignment="Top"  HorizontalContentAlignment="Right" HorizontalAlignment="Center" Width="69" Grid.RowSpan="2" />
 <ComboBox x:Name="optBedOccupancyLeft"  VerticalAlignment="Top" Height="26" Grid.RowSpan="2" HorizontalAlignment="Center" Width="170" Margin="0,240,0,0"/>
 <Label Content="Bed Occupancy" Margin="0,240,270,0" VerticalAlignment="Top" HorizontalContentAlignment="Right" Grid.RowSpan="2" HorizontalAlignment="Center" Width="94"/>
//.......
  <ComboBox Name="optMenuRight"  Margin="255,271,175,0" Grid.Column="1" VerticalAlignment="Top" Height="26" HorizontalAlignment="Center" Width="170"/>
  <Label Content="Menu" Margin="176,271,353,0" Grid.Column="1" VerticalAlignment="Top"  HorizontalContentAlignment="Right" HorizontalAlignment="Center" Width="71"/>
  <ComboBox Name="optBedOccupancyRight"  Margin="255,240,175,0" Grid.Column="1" VerticalAlignment="Top" Height="26" HorizontalAlignment="Center" Width="170" Grid.RowSpan="2"/>
  <Label Content="Bed Occupancy" Grid.Column="1" Margin="0,240,200,0" VerticalAlignment="Top" HorizontalContentAlignment="Right" Grid.RowSpan="2" HorizontalAlignment="Center" Width="94"/>
//.....

Upvotes: 0

Views: 669

Answers (2)

Liero
Liero

Reputation: 27360

The simplest way is to use grids inside grid. The outer grid will split the window into two columns. The inner grids will split the columns into four cells (2x2). Just center the inner grids and it will work like a charm.

<Grid x:Name="LayoutRoot">
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>

    <Grid x:Name="LeftColumn" VerticalAlignment="Center" HorizontalAlignment="Center">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>

        <Label Content="Bed Occupancy" />
        <ComboBox x:Name="optBedOccupancyLeft"  Grid.Column="1" />

        <Label Content="Menu" Grid.Row="1"/>
        <ComboBox  x:Name="optMenuLeft" Grid.Column="1" Grid.Row="1" />
    </Grid>

    <Grid x:Name="RightColumn" VerticalAlignment="Center" HorizontalAlignment="Center>
        <!-- the same as left column -->
    </Grid>

</Grid>

Btw, notice, that when you want split some are to equal columns (or rows or both), you can use UniformGrid:

<UniformGrid x:Name="LayoutRoot" Rows="1">
    <Grid x:Name="LeftColumn" />
    <Grid x:Name="RightColumn" />
</UniformGrid>

Upvotes: 1

Liero
Liero

Reputation: 27360

There is also more advanced approach that I often use:

  1. Use UniformGrid to define columns. The xaml is smaller and cleaner.
  2. Use HeaderedContentControl to define labels and inputs
  3. Use Grid's SharedSizeScope feature, to make width of label equal: https://msdn.microsoft.com/en-us/library/system.windows.controls.grid.issharedsizescope%28v=vs.110%29.aspx
<UniformGrid x:Name="LayoutRoot" Rows="1">

    <StackPanel x:Name="LeftColumn" Grid.IsSharedSizeScope="True"
                HorizontalAlignment="Center" VerticalAlignment="Center">

        <HeaderedContentControl Header="Bed Occupancy" Style="{StaticResource LabelValueContentControl}">
            <ComboBox x:Name="optBedOccupancyLeft" />
        </HeaderedContentControl>

        <HeaderedContentControl Header="Menu" Style="{StaticResource LabelValueContentControl}" >
            <ComboBox x:Name="optMenuLeft" />
        </HeaderedContentControl>
    </StackPanel>

    <StackPanel x:Name="RightColumn"  Grid.IsSharedSizeScope="True">
        <!-- the same as left column -->
    </StackPanel>

</UniformGrid>

The LabelCalueControlStyle is take advantage of shared column size

<Style x:Key="LabelValueContentControl" TargetType="HeaderedContentControl">
    <Setter Property="Padding" Value="5" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="HeaderedContentControl">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" SharedSizeGroup="LabelValueContentControl.Label" />
                        <ColumnDefinition Width="*"  />
                    </Grid.ColumnDefinitions>

                    <ContentPresenter ContentSource="Header" 
                                        Margin="{TemplateBinding Padding}" 
                                        HorizontalAlignment="Right" />

                    <ContentPresenter Grid.Column="1" Margin="{TemplateBinding Padding}" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Upvotes: 1

Related Questions