In a WPF Project I have a Grid
defined with two rows each containing a ListBox
. The RowDefinition
s have their Height = '*'
so equal space is allocated to each ListBox
. What I would like to happen however, is that when either ListBox
is not fully needing all its own space (through items being removed at runtime) then that 'spare' space is given over to the other ListBox
.
So, using the code I list below, both ListBox
's start off with equal space which is correct. Pressing the button deletes some entries from the top ListBox
(topList), resulting in white space below the remaining 2 entries. It's this space I would like to be granted to the bottom ListBox
. And vice versa.
XAML:
<Window x:Class="FiftyPercentSplit.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:FiftyPercentSplit"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid Height="200">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button x:Name="btnDeleteFromTopList" Click="btnDeleteFromTopList_Click" Content="Delete from Top List"/>
<ListBox x:Name="topList" Grid.Row="1">
<ListBoxItem>1</ListBoxItem>
<ListBoxItem>2</ListBoxItem>
<ListBoxItem>3</ListBoxItem>
<ListBoxItem>4</ListBoxItem>
<ListBoxItem>5</ListBoxItem>
<ListBoxItem>6</ListBoxItem>
<ListBoxItem>7</ListBoxItem>
<ListBoxItem>8</ListBoxItem>
<ListBoxItem>9</ListBoxItem>
</ListBox>
<ListBox x:Name="bottomList" Grid.Row="2">
<ListBoxItem>1</ListBoxItem>
<ListBoxItem>2</ListBoxItem>
<ListBoxItem>3</ListBoxItem>
<ListBoxItem>4</ListBoxItem>
<ListBoxItem>5</ListBoxItem>
<ListBoxItem>6</ListBoxItem>
<ListBoxItem>7</ListBoxItem>
<ListBoxItem>8</ListBoxItem>
<ListBoxItem>9</ListBoxItem>
</ListBox>
</Grid>
</Window>
Code behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void btnDeleteFromTopList_Click(object sender, RoutedEventArgs e)
{
for (int i = 0; i < 7; i++)
{
topList.Items.RemoveAt(0);
}
}
}
effectively the 2nd row should behave as Auto
-height row. But scrollable controls like ListBox don't work well in Auto
-height row - they grow infinitely and don't show scroll. To overcome it I usually have to set MaxHeight
.
In this case I left 2 RowDefinitions with Height="*", used element with name Measurer
to get actual height of the rows and set the MaxHeight
for topList
from ActualHeight
of Measurer. Note also that I used a nested Grid with <RowDefinition Height="Auto"/>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button x:Name="btnDeleteFromTopList" Click="btnDeleteFromTopList_Click" Content="Del"/>
<Border Grid.Row="2" Name="Measurer"/>
<Grid Grid.Row="1" Grid.RowSpan="2">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<ListBox Grid.Row="0" x:Name="topList" VerticalAlignment="Top"
MaxHeight="{Binding ActualHeight, ElementName=Measurer}">
</ListBox>
<ListBox x:Name="bottomList" Grid.Row="1">
</ListBox>
</Grid>
</Grid>