Question

I'm trying to build a layout that would fix the bottom of two rows to be always visible. the problem is, the content of the bottom row has to be at the top, which makes it difficult to use a dockpanel. here's a short overview:

here is a link with pictures for all the windows:

(sorry about that, but stackoverflow won't let me post images yet..)

the first window is how it's supposed to look when there's plenty space available, the bottom (blue) sticks to the top (red).

the code looks like this:

<DockPanel>

    <Grid VerticalAlignment="Top"
          Background="Red"
          DockPanel.Dock="Top">
        <Grid Height="100" />
    </Grid>

    <Grid Height="20"
          Background="Blue"
          VerticalAlignment="Top"
          DockPanel.Dock="Bottom" />

</DockPanel>

but when I size the window so the second row doesn't fit anymore, the second row is not fixed and will be invisible when the window is too small: window 2

so what I want is something like this:

<DockPanel>
    <Grid Height="20"
          Background="Blue"
          DockPanel.Dock="Bottom" />

    <Grid VerticalAlignment="Top"
          Background="Red"
          DockPanel.Dock="Top">
        <Grid Height="100" />
    </Grid>
</DockPanel>

which gives me the following with enough space available: window 3

and this when I resize the window: window 4

the bottom is fixed. The problem here is, when there's too much space, the second row doesn't stick to the top, but to the bottom like in the third picture. I've played around with DockPanel.LastChildFill and the child order in a dockpanel. I've tried various layouts using one or more grids but couldn't get it to work. how would I go about doing this?

edit: @publicgk:you're right, the second window was the wrong one, I updated the link.

Moreover, I'll try to explain myself a little better. Considering the first row is completely red, and the second row is the rest (blue and white together). Then the first code sample gives me the first and the second window: While the content of the second row (the blue part) is at the top (window1, which is what I want), the second row is not fixed/always visible when i resize the window (window 2).

The second code sample produces window 3 and 4, while the content is at the bottom of the second row when the window is big enough (window 3, not what I want), the second row is visible even when I resize the window (window 4, that's what i want), so the second row is overlapping the first.

To sum it up i need the rows to behave like window 1 when there's enough space, and like window 4 when there's not.

Edit2: I forgot to mention, the first row is supposed to hold contents, of which the size is unknown and variable, so using a grid and setting height or maxheight of the first row won't work. the height of the second row however is known and may be set directly.

here's a sample, which shows this problem:

<Window x:Class="WpfApplication2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication2"
    Title="MainWindow"
    Width="525"
    Height="350">
<Window.Resources>
    <local:RandomHeightConverter x:Key="RandomHeightConverter"/>
</Window.Resources>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="100*" MaxHeight="100"/>
        <RowDefinition Height="20" />
    </Grid.RowDefinitions>

    <Grid Grid.Row="0"  Background="Red" Height="{Binding Converter={StaticResource RandomHeightConverter}}" />
    <Grid Grid.Row="1"  Background="Blue"  />
</Grid>

public class RandomHeightConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return new Random().Next(20, 100);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

that would produce results like this: variable first row problem

Was it helpful?

Solution

Not sure if you can do this layout using DockPanel, but you may be able to use Grid to do this sort of layout.

Something like this replicates what you are trying to do

<Window x:Class="WpfApplication9.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication9"
        Title="MainWindow" Height="209" Width="525" Name="UI">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="100*" MaxHeight="100" />
                <RowDefinition Height="20" />
            </Grid.RowDefinitions>
            <Grid Grid.Row="0"  Background="Red" />
            <Grid Grid.Row="1"  Background="Blue"  />
        </Grid>
</Window>

Or bind the RowDefinition sizes to the contents you want to show, so in the below example the top sction will size to fix its contents but can shrink, the bottom row is fixed size to the bottom content and will overlap when the window is sized smaller than the Top row.

 <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" MaxHeight="{Binding ElementName=topContent, Path=ActualHeight, Mode=OneTime}" />
            <RowDefinition Height="{Binding ElementName=bottomContent, Path=ActualHeight,Mode=OneTime}"  />
        </Grid.RowDefinitions>
        <Grid x:Name="topContent" Grid.Row="0"  >
            <!--your top content-->
            <Grid Height="200" Background="Red" />
        </Grid>
        <Grid Grid.Row="1"  >
            <!--your bottom content-->
            <Grid x:Name="bottomContent" VerticalAlignment="Top" Height="20" Background="Blue" />
        </Grid>
    </Grid>

Result:

enter image description here enter image description here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top