Scroll AND Stretch the content of an Expander Scroll AND Stretch the content of an Expander wpf wpf

Scroll AND Stretch the content of an Expander


I think what you're looking for is a mix of Auto and * sized Rows: Auto when collapsed, * when expanded. There are a lot of ways you can achieve this switching. A simple one is to bind the row heights to the expanders through a converter. The XAML would look like this:

<Grid Background="LightBlue" Grid.Row="1" >    <Grid.RowDefinitions>        <RowDefinition Height="{Binding ElementName=Ex1, Path=IsExpanded, Converter={StaticResource ExpandedToGridLengthConverter}}" />        <RowDefinition Height="{Binding ElementName=Ex2, Path=IsExpanded, Converter={StaticResource ExpandedToGridLengthConverter}}" />        <RowDefinition Height="{Binding ElementName=Ex3, Path=IsExpanded, Converter={StaticResource ExpandedToGridLengthConverter}}" />        <RowDefinition Height="{Binding ElementName=Ex4, Path=IsExpanded, Converter={StaticResource ExpandedToGridLengthConverter}}" />    </Grid.RowDefinitions>    <Expander Grid.Row="0" x:Name="Ex1" ...>        <RichTextBox ... />    </Expander>    <Expander Grid.Row="1" x:Name="Ex2" ...>        ...    </Expander>    ...</Grid>

And here's a simple version of the converter:

public class ExpandedToGridLengthConverter : IValueConverter{    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)    {        if (!(value is bool))            return GridLength.Auto;        if ((bool)value)            return new GridLength(1, GridUnitType.Star);        return GridLength.Auto;    }    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)    {        throw new NotImplementedException();    }}

Now the available space will be split between the open expanders and the collapsed ones will only take up as much as their header needs. If the text gets too long for one of the expanded ones the ScrollViewer should take over and start scrolling the text inside that * area.


I recently had to do something like this. I used very similar code to what you have but was able to achieve the desired result using the code behind the page. Try something like this:

WPF

<Grid Grid.Row="1"        Name="pageGrid" Margin="0,10,0,0">        <Grid.RowDefinitions>            <RowDefinition                MinHeight="25"                Height="*" />            <RowDefinition                MinHeight="25"                Height="*" />            <RowDefinition                MinHeight="25"                Height="*" />            <RowDefinition                MinHeight="25"                Height="*" />            <RowDefinition                MinHeight="25"                Height="*" />            <RowDefinition                MinHeight="25"                Height="*" />            <RowDefinition                MinHeight="25"                Height="*" />        </Grid.RowDefinitions>        <Expander            Grid.Row="0"            Header="header1"            Name="expander1"            Margin="0,0,0,0"            VerticalAlignment="Top"            FontSize="18"            IsExpanded="True">            <Grid>                <TextBlock                    Background="#336699FF"                    Padding="5"                    TextWrapping="Wrap"                    Margin="30,5,10,5">                                    test                </TextBlock>            </Grid>        </Expander>        <Expander            Grid.Row="1"            Header="header2"            Margin="0,0,0,0"            Name="expander2"            VerticalAlignment="Top"            FontSize="18">            <Grid>                <TextBlock                    Background="#336699FF"                    Padding="5"                    TextWrapping="Wrap"                    Margin="30,5,10,5">                        test                </TextBlock>            </Grid>        </Expander>        <Expander            Grid.Row="2"            Header="header3"            Margin="0,0,0,0"            Name="expander3"            VerticalAlignment="Top"            FontSize="18">            <Grid>                <TextBlock                    Background="#336699FF"                    Padding="5"                    TextWrapping="Wrap"                    Margin="30,5,10,5">                        test                </TextBlock>            </Grid>        </Expander>        <Expander            Grid.Row="3"            Header="header4"            Margin="0,0,0,0"            Name="expander4"            VerticalAlignment="Top"            FontSize="18">            <Grid>                <TextBlock                    Background="#336699FF"                    Padding="5"                    TextWrapping="Wrap"                    Margin="30,5,10,5">                    test                </TextBlock>            </Grid>        </Expander>        <Expander            Grid.Row="4"            Header="header5"            Margin="0,0,0,0"            Name="expander5"            VerticalAlignment="Top"            FontSize="18">            <Grid>                <TextBlock                    Background="#336699FF"                    Padding="5"                    TextWrapping="Wrap"                    Margin="30,5,10,5">                    test                </TextBlock>            </Grid>        </Expander>        <Expander            Grid.Row="5"            Header="header6"            Margin="0,0,0,0"            Name="expander6"            VerticalAlignment="Top"            FontSize="18">            <Grid>                <TextBlock                    Background="#336699FF"                    Padding="5"                    TextWrapping="Wrap"                    Margin="30,5,10,5">                    test                </TextBlock>            </Grid>        </Expander>        <Expander            Grid.Row="6"            Header="header7"            Margin="0,0,0,0"            Name="expander7"            VerticalAlignment="Top"            FontSize="18">            <Grid>                <TextBlock Background="#336699FF" Padding="5"                    TextWrapping="Wrap"                    Margin="30,5,10,5">                    text                </TextBlock>            </Grid>        </Expander>    </Grid>

In the window code behind I used C# and have this code:

C#

/// <summary>/// Interaction logic for _07Slide.xaml/// </summary>public partial class _07Slide : Page{    GridLength[] starHeight;    public _07Slide()    {        InitializeComponent();        starHeight = new GridLength[pageGrid.RowDefinitions.Count];        starHeight[0] = pageGrid.RowDefinitions[0].Height;        starHeight[1] = pageGrid.RowDefinitions[2].Height;        starHeight[2] = pageGrid.RowDefinitions[2].Height;        starHeight[3] = pageGrid.RowDefinitions[2].Height;        starHeight[4] = pageGrid.RowDefinitions[2].Height;        starHeight[5] = pageGrid.RowDefinitions[2].Height;        starHeight[6] = pageGrid.RowDefinitions[2].Height;        ExpandedOrCollapsed(expander1);        ExpandedOrCollapsed(expander2);        ExpandedOrCollapsed(expander3);        ExpandedOrCollapsed(expander4);        ExpandedOrCollapsed(expander5);        ExpandedOrCollapsed(expander6);        ExpandedOrCollapsed(expander7);        expander1.Expanded += ExpandedOrCollapsed;        expander1.Collapsed += ExpandedOrCollapsed;        expander2.Expanded += ExpandedOrCollapsed;        expander2.Collapsed += ExpandedOrCollapsed;        expander3.Expanded += ExpandedOrCollapsed;        expander3.Collapsed += ExpandedOrCollapsed;        expander4.Expanded += ExpandedOrCollapsed;        expander4.Collapsed += ExpandedOrCollapsed;        expander5.Expanded += ExpandedOrCollapsed;        expander5.Collapsed += ExpandedOrCollapsed;        expander6.Expanded += ExpandedOrCollapsed;        expander6.Collapsed += ExpandedOrCollapsed;        expander7.Expanded += ExpandedOrCollapsed;        expander7.Collapsed += ExpandedOrCollapsed;    }    void ExpandedOrCollapsed(object sender, RoutedEventArgs e)    {        ExpandedOrCollapsed(sender as Expander);    }    void ExpandedOrCollapsed(Expander expander)    {        var rowIndex = Grid.GetRow(expander);        var row = pageGrid.RowDefinitions[rowIndex];        if (expander.IsExpanded)        {            row.Height = starHeight[rowIndex];            row.MinHeight = 25;                        }        else        {            starHeight[rowIndex] = row.Height;            row.Height = GridLength.Auto;            row.MinHeight = 0;        }    }}

In this example the expanders will all grow to fill the grid completely. If you wanted to you could modify this to collapse the other expanders when one is selected.