Vidar
Vidar

Reputation: 6673

Make a ListBox in an Expander not overrun other controls and scroll

I want to show a ListBox with many items inside an expander control. I don't want to specify the height of the ListBox as I want the fluid/flex type responsiveness in my UI to be retained - so explicit height specifications are not the way here.

What happens at the moment is, after the expander is expanded, the ListBox overruns the whole interface and doesn't show a scrollbar. Is there a way for the expander to respect the controls beneath it, show a scrollbar and size appropriately.

Here is a screenshot before and after showing the behavior:

enter image description here

Here is a screenshot of a mocked up version of how I want the UI to actually look like:

enter image description here

And here is the basic wpf xaml code I have:

   <Grid ShowGridLines="False">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
   </Grid.RowDefinitions>

    <Expander Grid.Row="0" Header="A long list of stuff" Margin="5" >
        <ListBox Margin="5" >
            <ListBoxItem>ListBox Item #1</ListBoxItem>
            <ListBoxItem>ListBox Item #2</ListBoxItem>
            <ListBoxItem>ListBox Item #3</ListBoxItem>
            <ListBoxItem>ListBox Item #1</ListBoxItem>
            <ListBoxItem>ListBox Item #2</ListBoxItem>
            <ListBoxItem>ListBox Item #3</ListBoxItem>
            <ListBoxItem>ListBox Item #1</ListBoxItem>
            <ListBoxItem>ListBox Item #2</ListBoxItem>
            <ListBoxItem>ListBox Item #3</ListBoxItem>
            <ListBoxItem>ListBox Item #1</ListBoxItem>
            <ListBoxItem>ListBox Item #2</ListBoxItem>
            <ListBoxItem>ListBox Item #3</ListBoxItem>
            <ListBoxItem>ListBox Item #1</ListBoxItem>
            <ListBoxItem>ListBox Item #2</ListBoxItem>
            <ListBoxItem>ListBox Item #3</ListBoxItem>
            <ListBoxItem>ListBox Item #1</ListBoxItem>
            <ListBoxItem>ListBox Item #2</ListBoxItem>
            <ListBoxItem>ListBox Item #3</ListBoxItem>
            <ListBoxItem>ListBox Item #1</ListBoxItem>
            <ListBoxItem>ListBox Item #2</ListBoxItem>
            <ListBoxItem>ListBox Item #3</ListBoxItem>
            <ListBoxItem>ListBox Item #1</ListBoxItem>
            <ListBoxItem>ListBox Item #2</ListBoxItem>
            <ListBoxItem>ListBox Item #3</ListBoxItem>
            <ListBoxItem>ListBox Item #1</ListBoxItem>
            <ListBoxItem>ListBox Item #2</ListBoxItem>
            <ListBoxItem>ListBox Item #3</ListBoxItem>
            <ListBoxItem>ListBox Item #1</ListBoxItem>
            <ListBoxItem>ListBox Item #2</ListBoxItem>
            <ListBoxItem>ListBox Item #3</ListBoxItem>
        </ListBox>
    </Expander>


    <Expander Grid.Row="1" Header="List of stuff" Margin="5" >
        <ListBox Margin="5" >
            <ListBoxItem>ListBox Item #1</ListBoxItem>
            <ListBoxItem>ListBox Item #2</ListBoxItem>
            <ListBoxItem>ListBox Item #3</ListBoxItem>
            <ListBoxItem>ListBox Item #1</ListBoxItem>
            <ListBoxItem>ListBox Item #3</ListBoxItem>
            <ListBoxItem>ListBox Item #1</ListBoxItem>
        </ListBox>
    </Expander>

    <Expander Grid.Row="2" Header="List of more stuff" Margin="5"  >
        <ListBox Margin="5" >
            <ListBoxItem>ListBox Item #1</ListBoxItem>
            <ListBoxItem>ListBox Item #2</ListBoxItem>
            <ListBoxItem>ListBox Item #3</ListBoxItem>
            <ListBoxItem>ListBox Item #1</ListBoxItem>
            <ListBoxItem>ListBox Item #2</ListBoxItem>
            <ListBoxItem>ListBox Item #3</ListBoxItem>
            <ListBoxItem>ListBox Item #1</ListBoxItem>
            <ListBoxItem>ListBox Item #2</ListBoxItem>
            <ListBoxItem>ListBox Item #3</ListBoxItem>
            <ListBoxItem>ListBox Item #1</ListBoxItem>
            <ListBoxItem>ListBox Item #2</ListBoxItem>
            <ListBoxItem>ListBox Item #3</ListBoxItem>
            <ListBoxItem>ListBox Item #1</ListBoxItem>
            <ListBoxItem>ListBox Item #2</ListBoxItem>
            <ListBoxItem>ListBox Item #3</ListBoxItem>
        </ListBox>
    </Expander>

</Grid>

Upvotes: 1

Views: 311

Answers (1)

Cortez
Cortez

Reputation: 96

You can do this by changing the alignment of your grid to 'Top' and adding 2 events to all your Expanders

<Grid VerticalAlignment="Top">
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="auto"/>
        </Grid.RowDefinitions>
        <Expander Grid.Row="0" Header="A long list of stuff" Margin="5" Expanded="Expander_Expanded" Collapsed="Expander_Collapsed">
            <ListBox Margin="5" >
                <ListBoxItem>ListBox Item #1</ListBoxItem>
                <ListBoxItem>ListBox Item #2</ListBoxItem>
                <ListBoxItem>ListBox Item #3</ListBoxItem>
                <ListBoxItem>ListBox Item #1</ListBoxItem>
                <ListBoxItem>ListBox Item #2</ListBoxItem>
                <ListBoxItem>ListBox Item #3</ListBoxItem>
                <ListBoxItem>ListBox Item #1</ListBoxItem>
                <ListBoxItem>ListBox Item #2</ListBoxItem>
                <ListBoxItem>ListBox Item #3</ListBoxItem>
                <ListBoxItem>ListBox Item #1</ListBoxItem>
                <ListBoxItem>ListBox Item #2</ListBoxItem>
                <ListBoxItem>ListBox Item #3</ListBoxItem>
                <ListBoxItem>ListBox Item #1</ListBoxItem>
                <ListBoxItem>ListBox Item #2</ListBoxItem>
                <ListBoxItem>ListBox Item #3</ListBoxItem>
                <ListBoxItem>ListBox Item #1</ListBoxItem>
                <ListBoxItem>ListBox Item #2</ListBoxItem>
                <ListBoxItem>ListBox Item #3</ListBoxItem>
                <ListBoxItem>ListBox Item #1</ListBoxItem>
                <ListBoxItem>ListBox Item #2</ListBoxItem>
                <ListBoxItem>ListBox Item #3</ListBoxItem>
                <ListBoxItem>ListBox Item #1</ListBoxItem>
                <ListBoxItem>ListBox Item #2</ListBoxItem>
                <ListBoxItem>ListBox Item #3</ListBoxItem>
                <ListBoxItem>ListBox Item #1</ListBoxItem>
                <ListBoxItem>ListBox Item #2</ListBoxItem>
                <ListBoxItem>ListBox Item #3</ListBoxItem>
                <ListBoxItem>ListBox Item #1</ListBoxItem>
                <ListBoxItem>ListBox Item #2</ListBoxItem>
                <ListBoxItem>ListBox Item #3</ListBoxItem>
            </ListBox>
        </Expander>


        <Expander Grid.Row="1" Header="List of stuff" Margin="5" Expanded="Expander_Expanded" Collapsed="Expander_Collapsed">
            <ListBox Margin="5" >
                <ListBoxItem>ListBox Item #1</ListBoxItem>
                <ListBoxItem>ListBox Item #2</ListBoxItem>
                <ListBoxItem>ListBox Item #3</ListBoxItem>
                <ListBoxItem>ListBox Item #1</ListBoxItem>
                <ListBoxItem>ListBox Item #3</ListBoxItem>
                <ListBoxItem>ListBox Item #1</ListBoxItem>
            </ListBox>
        </Expander>

        <Expander Grid.Row="2" Header="List of more stuff" Margin="5" Expanded="Expander_Expanded" Collapsed="Expander_Collapsed">
            <ListBox Margin="5" >
                <ListBoxItem>ListBox Item #1</ListBoxItem>
                <ListBoxItem>ListBox Item #2</ListBoxItem>
                <ListBoxItem>ListBox Item #3</ListBoxItem>
                <ListBoxItem>ListBox Item #1</ListBoxItem>
                <ListBoxItem>ListBox Item #2</ListBoxItem>
                <ListBoxItem>ListBox Item #3</ListBoxItem>
                <ListBoxItem>ListBox Item #1</ListBoxItem>
                <ListBoxItem>ListBox Item #2</ListBoxItem>
                <ListBoxItem>ListBox Item #3</ListBoxItem>
                <ListBoxItem>ListBox Item #1</ListBoxItem>
                <ListBoxItem>ListBox Item #2</ListBoxItem>
                <ListBoxItem>ListBox Item #2</ListBoxItem>
                <ListBoxItem>ListBox Item #3</ListBoxItem>
                <ListBoxItem>ListBox Item #1</ListBoxItem>
                <ListBoxItem>ListBox Item #2</ListBoxItem>
                <ListBoxItem>ListBox Item #3</ListBoxItem>
                <ListBoxItem>ListBox Item #1</ListBoxItem>
                <ListBoxItem>ListBox Item #2</ListBoxItem>
                <ListBoxItem>ListBox Item #3</ListBoxItem>
                <ListBoxItem>ListBox Item #1</ListBoxItem>
                <ListBoxItem>ListBox Item #2</ListBoxItem>
                <ListBoxItem>ListBox Item #3</ListBoxItem>
                <ListBoxItem>ListBox Item #1</ListBoxItem>
                <ListBoxItem>ListBox Item #2</ListBoxItem>
                <ListBoxItem>ListBox Item #3</ListBoxItem>
                <ListBoxItem>ListBox Item #2</ListBoxItem>
                <ListBoxItem>ListBox Item #3</ListBoxItem>
                <ListBoxItem>ListBox Item #1</ListBoxItem>
                <ListBoxItem>ListBox Item #2</ListBoxItem>
                <ListBoxItem>ListBox Item #3</ListBoxItem>
                <ListBoxItem>ListBox Item #1</ListBoxItem>
                <ListBoxItem>ListBox Item #2</ListBoxItem>
                <ListBoxItem>ListBox Item #3</ListBoxItem>
                <ListBoxItem>ListBox Item #1</ListBoxItem>
                <ListBoxItem>ListBox Item #2</ListBoxItem>
                <ListBoxItem>ListBox Item #3</ListBoxItem>
                <ListBoxItem>ListBox Item #1</ListBoxItem>
                <ListBoxItem>ListBox Item #2</ListBoxItem>
                <ListBoxItem>ListBox Item #3</ListBoxItem>
                <ListBoxItem>ListBox Item #3</ListBoxItem>
                <ListBoxItem>ListBox Item #1</ListBoxItem>
                <ListBoxItem>ListBox Item #2</ListBoxItem>
                <ListBoxItem>ListBox Item #3</ListBoxItem>
            </ListBox>
        </Expander>
    </Grid>
private void Expander_Expanded(object sender, RoutedEventArgs e)
{
    var expander = (Expander)sender;
    var row = Grid.GetRow(expander);
    ((Grid)expander.Parent).RowDefinitions[row].Height = new GridLength(1, GridUnitType.Star);
}

private void Expander_Collapsed(object sender, RoutedEventArgs e)
{
    var expander = (Expander)sender;
    var row = Grid.GetRow(expander);
    ((Grid)expander.Parent).RowDefinitions[row].Height = new GridLength(1, GridUnitType.Auto);
}

Upvotes: 2

Related Questions