Search code examples
c#wpfwindowsautosize

Auto Sizing c# WPF windows anything smaller it goes off the screen


I am trying to set the WPF window to resize depending on the resolution however, I cannot seem to get it right. Does anyone have any suggestions or articles I should read to achieve this?

I have included some sample code that i have tried as a base to work off.

This code works fine at 1920 by 1080 but anything smaller it goes off the screen

Any help would be greatly appreciated, thanks in advance!

<WindowState="Maximized" WindowStyle="SingleBorderWindow">
    <Grid Margin="0,0,2,-21" RenderTransformOrigin="0.0,0.0">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Image HorizontalAlignment="Right" Height="100" Margin="0,30,-400,0" VerticalAlignment="Top" Width="145" Source="G:\Pi Project\Project Pi Logo.png" Grid.Column="1"/>
        <Label Content="The Pi Project" HorizontalAlignment="Right" Height="60" Margin="0,132,-390,0" VerticalAlignment="Top" Width="170" FontSize="16" Grid.Column="1" />
        <Button x:Name="saveProject_btn" Content=" Save&#xD;&#xA;Project" HorizontalAlignment="Right" Height="200" Margin="0,815,-415,0" VerticalAlignment="Top" Width="300" FontFamily="OCR A Extended" FontSize="36" Grid.Column="1"/>
        <Button x:Name="home_btn" Content="Return&#xD;&#xA; Home" HorizontalAlignment="Right" Height="200" Margin="0,600,-415,0" VerticalAlignment="Top" Width="300" FontFamily="OCR A Extended" FontSize="36" Click="home_btn_Click"/>
        <Label x:Name="projectCodeViewer" Content="" HorizontalAlignment="Left" Height="560" Margin="50,455,0,0" VerticalAlignment="Top" Width="1425" BorderThickness="2,2,2,2" BorderBrush="Black" FontSize="36" FontFamily="OCR A Extended" Grid.ColumnSpan="2"/>
        <ListBox x:Name="MoveCommands_LB" HorizontalAlignment="Left" Height="289" Margin="50,30,0,0" VerticalAlignment="Top" Width="648" SelectionChanged="Movement_List_Populate" Grid.ColumnSpan="2"/>
        <ListBox x:Name="Values_LB" HorizontalAlignment="Left" Height="289" Margin="735,30,0,0" VerticalAlignment="Top" Width="328"/>
        <Button Content="Add Command" HorizontalAlignment="left" Height="289" Margin="1100,30,-53,0" VerticalAlignment="Top" Width="428" FontSize="48"/>
    </Grid>

Solution

  • In XAML if you want to automatically position any kind of Object on your window it is highly discouraged (in my point of view) to set margins that could make your Objects go out of bounds.

    You also have to think where you want to position them and how they should react when you resize them, for example, if you have a header that's supposed to use the entire Width of the Parent control (in this case Window), then it should have no Width, HorizontalAlignment set to Stretch and no Margins (except if you want to make it have a free space from all sides)

    Another example would be a Button that is used to close your Window, the best practice would be to actually place it on the bottom right with HorizontalAlignment set to Right and VerticalAlignment set to Bottom with no Margins, except like above, you want to make it have some padding off the corners.

    That way when you resize everything flows perfectly to the places relative to the size of the Window, keeping the same proportions, here an example of what I explained above:

    <Grid>
        <Label Content="Header" VerticalAlignment="Top" FontSize="20" FontWeight="Bold" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Height="50" BorderThickness="3" BorderBrush="Black" Background="Beige"/>
        <!-- Inside this Grid we insert the Body -->
        <Grid Margin="5,55,5,60" Background="LightGray" >
            <Grid.Effect>
                <DropShadowEffect />
            </Grid.Effect>
            <Label Content="Hello World!" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="50" />
        </Grid>
        <Button Content="Exit" VerticalAlignment="Bottom" HorizontalAlignment="Right" Height="50" Width="100" Margin="0,0,5,5" />
    </Grid>
    

    What I did above is still not how you could resolve it the best way, because I'm setting Margins and not defining a "set structure", for that the Grid object has a great feature, ColumnDefinitions and RowDefinitions, below is the same code but with those definitions that help me define sections in my XAML structure:

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="50" />
            <RowDefinition />
            <RowDefinition Height="50" />
        </Grid.RowDefinitions>
        <Label Content="Header" Grid.Row="0" VerticalAlignment="Top" FontSize="20" FontWeight="Bold" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Height="50" BorderThickness="3" BorderBrush="Black" Background="Beige"/>
        <!-- Inside this Grid we insert the Body -->
        <Grid Grid.Row="1" Margin="5,5,5,10" Background="LightGray" >
            <Grid.Effect>
                <DropShadowEffect />
            </Grid.Effect>
            <Label Content="Hello World!" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="50" />
        </Grid>
        <Button Content="Exit" Grid.Row="2" VerticalAlignment="Bottom" HorizontalAlignment="Right" Height="50" Width="100" Margin="0,0,5,5" />
    </Grid>
    

    So all you gotta do is actually structure that Resizable layout you're making like I did and you're set.