tags:

views:

159

answers:

1

I have two user controls arranged vertically in a grid, both of which can expand to be taller than the grid can accommodate. I've put them in each in a scrollviewer which functionally works. What I want though is to give them them space in proportion to the amount that they want at run time.

So if there's 500 height available, the upper control wants 400 and the lower 600, the upper control would get 200 and the bottom 300.

I have no idea at design time how much space each will want in proportion to the other, so using 1*, 2* etc. for row height won't work for me.

I can hand-code run-time proportional sizing, but am I missing a simple trick in XAML that would get me what I want?

Context is as follows (trimmed for brevity)...

<Grid>
    <TabControl>
        <TabItem>
            <Grid>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="*"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
                    <GroupBox Grid.Row="0" Header="Title Area" />
                    <ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
                        <UserControl />
                    </ScrollViewer>
                    <ScrollViewer Grid.Row="2" VerticalScrollBarVisibility="Auto">
                        <UserControl />
                    </ScrollViewer>
                </Grid> 
            </Grid>
        </TabItem>
    </TabControl>    
</Grid>
+1  A: 

I'll take it that there's no easy way of doing it in XAML, so I have resorted to code-behind. The way I've done it is thus, in the XAML;

<Grid>
    <TabControl>
        <TabItem>
            <Grid>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Name="FooRow" Height="*"/>
                        <RowDefinition Name="BarRow" Height="*"/>
                    </Grid.RowDefinitions>
                    <GroupBox Grid.Row="0" Header="Title Area" />
                    <ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
                        <UserControl Name="Foo" SizeChanged="Foo_SizeChanged" />
                    </ScrollViewer>
                    <ScrollViewer Grid.Row="2" VerticalScrollBarVisibility="Auto">
                        <UserControl Name="Bar" SizeChanged="Bar_SizeChanged" />
                    </ScrollViewer>
                </Grid>
            </Grid>
        </TabItem>
    </TabControl>
</Grid>

In the code-behind;

    private void Foo_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        FooRow.Height = new GridLength(e.NewSize.Height, GridUnitType.Star);
    }

    private void Bar_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        BarRow.Height = new GridLength(e.NewSize.Height, GridUnitType.Star);
    }

You could also do it with bindings and a ValueConverter.

sinibar