#917 – Changing Something when an Expander Is Expanded

You can use a trigger to change some property in an Expander whenever the Expander is expanded.  You set the trigger to react to a change in the IsExpanded property.

In the example below, we define a trigger that changes the border color for any expander that is expanded.

    <Window.Resources>
        <Style x:Key="changeColorOnExpanded" TargetType="Expander">
            <Setter Property="BorderBrush" Value="DarkGray"/>
            <Setter Property="Margin" Value="10,5"/>
            <Style.Triggers>
                <Trigger Property="IsExpanded" Value="True">
                    <Setter Property="BorderBrush" Value="Crimson"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>

    <StackPanel>
        <Expander Style="{StaticResource changeColorOnExpanded}"
                  Header="Great Novels">
            <ScrollViewer>
                <StackPanel>
                    <TextBlock Text="Ulysses"/>
                    <TextBlock Text="The Great Gatsby"/>
                    <TextBlock Text="A Portrait of the Artist as a Young Man"/>
                    <TextBlock Text="Lolita"/>
                </StackPanel>
            </ScrollViewer>
        </Expander>
        <Expander Style="{StaticResource changeColorOnExpanded}"
                  Header="Funny Guys">
            <ScrollViewer>
                <StackPanel>
                    <TextBlock Text="Bill Murray"/>
                    <TextBlock Text="Eddie Murphy"/>
                    <TextBlock Text="Will Ferrell"/>
                    <TextBlock Text="John Cleese"/>
                </StackPanel>
            </ScrollViewer>
        </Expander>
    </StackPanel>

917-001

Advertisement

#916 – Scrolling Content within an Expander Control

The content of an Expander is shown when the control is expanded.  If you want to be able to scroll the contents of the Expander, you can set its content to a ScrollViewer, as shown below.

    <StackPanel Margin="5">
        <Expander BorderBrush="DarkGray"
                  Header="Expand Me"    >
            <ScrollViewer>
                <StackPanel>
                    <TextBlock Text="Ulysses"/>
                    <!-- bunch more items go here -->
                </StackPanel>
            </ScrollViewer>
        </Expander>
        <TextBlock Text="I'm below the Expander"/>
    </StackPanel>

The problem with this is that the Expander will normally expand to fit its content.

916-001

To be able to scroll the content of the Expander, you need to constrain its height.  You can do this by setting the MaxHeight property.

<Expander BorderBrush="DarkGray"
Header="Expand Me"
MaxHeight="150">

916-002

 

#915 – Delaying Generation of Expander Content

If you have a lot of content to display when an Expander is expanded and you want to delay loading of the content until the user actually opens the Expander, you can use the Expander’s Expanded event.

In the example below, the Expander contains a TextBlock, which we only load in the handler for the Expanded event.

        <Expander BorderBrush="DarkGray" Margin="0,5"
                  Header="Expand to See Something"
                  Expanded="Expander_Expanded">
            <TextBlock Name="txtInfo"/>
        </Expander>
        private void Expander_Expanded(object sender, RoutedEventArgs e)
        {
            txtInfo.Text = string.Format("You expanded me at {0}", DateTime.Now);
        }

When we run this example, the date/time displayed is the date/time that you expand the Expander.
915-001

#914 – Drawing a Border Around an Expander

You can make the boundaries of an Expander control more clear if you draw a border around the control.  The style for an Expander already has a Border element, though it is not visible by default.  You can make it visible by setting the BorderBrush and BorderThickness properties on the Expander.

        <Expander BorderBrush="DarkGray" Margin="0,5">
            <Expander.Header>
                <Image Source="CptBlood-1935.png" Width="51" Height="72"/>
            </Expander.Header>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>

                <Label Grid.Row="0" Grid.Column="0" Content="Title" FontWeight="Bold"/>
                <Label Grid.Row="0" Grid.Column="1" Content="Captain Blood"/>

                <Label Grid.Row="1" Grid.Column="0" Content="Year" FontWeight="Bold"/>
                <Label Grid.Row="1" Grid.Column="1" Content="1935"/>

                <Label Grid.Row="2" Grid.Column="0" Content="Director" FontWeight="Bold"/>
                <Label Grid.Row="2" Grid.Column="1" Content="Michael Curtiz"/>

                <Label Grid.Row="3" Grid.Column="0" Content="Star" FontWeight="Bold"/>
                <Label Grid.Row="3" Grid.Column="1" Content="Errol Flynn"/>
            </Grid>
        </Expander>

914-001
914-002

#913 – Changing the Direction that an Expander Expands

By default, an Expander control expands down, placing the content of the Expander below the header, when the control is expanded.

912-002

You can cause the Expander to expand in a different direction using the ExpandDirection property.  Valid values are Up, Down, Left or Right.

        <Expander ExpandDirection="Right">
            <Expander.Header>
                <Image Source="CptBlood-1935.png" Width="51" Height="72"/>
            </Expander.Header>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>

                <Label Grid.Row="0" Grid.Column="0" Content="Title" FontWeight="Bold"/>
                <Label Grid.Row="0" Grid.Column="1" Content="Captain Blood"/>

                <Label Grid.Row="1" Grid.Column="0" Content="Year" FontWeight="Bold"/>
                <Label Grid.Row="1" Grid.Column="1" Content="1935"/>

                <Label Grid.Row="2" Grid.Column="0" Content="Director" FontWeight="Bold"/>
                <Label Grid.Row="2" Grid.Column="1" Content="Michael Curtiz"/>

                <Label Grid.Row="3" Grid.Column="0" Content="Star" FontWeight="Bold"/>
                <Label Grid.Row="3" Grid.Column="1" Content="Errol Flynn"/>
            </Grid>
        </Expander>

913-001

#912 – Expanding an Expander Will Trigger Layout

When you expand an Expander control, you retrigger a layout operation.  The parent control then lays out the new Expander control, using the expanded portion.

In the example below, we put two Expander controls in a vertical StackPanel.  When we expand the first one, the StackPanel lays out its child controls again, such that the second Expander shifts down below the first.

912-001

912-002

#510 – The Header of an Expander Can Be Anything

The Header property of an Expander control doesn’t have to be a string.  You can set it to any object and that object will be displayed at the top of the Expander, whether the Expander is collapsed or expanded.

In the example below, we use an Image for the header of the Expander and then a GroupBox for its content.

        <Expander Margin="10" >
            <Expander.Header>
                <Image Source="Images/CptBlood-1935.png" Width="51" Height="72"/>
            </Expander.Header>
            <GroupBox Header="More Info">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>

                    <Label Grid.Row="0" Grid.Column="0" Content="Title" FontWeight="Bold" HorizontalAlignment="Right"/>
                    <Label Grid.Row="0" Grid.Column="1" Content="Captain Blood"/>

                    <Label Grid.Row="1" Grid.Column="0" Content="Year" FontWeight="Bold" HorizontalAlignment="Right"/>
                    <Label Grid.Row="1" Grid.Column="1" Content="1935"/>

                    <Label Grid.Row="2" Grid.Column="0" Content="Director" FontWeight="Bold" HorizontalAlignment="Right"/>
                    <Label Grid.Row="2" Grid.Column="1" Content="Michael Curtiz"/>

                    <Label Grid.Row="3" Grid.Column="0" Content="Star" FontWeight="Bold" HorizontalAlignment="Right"/>
                    <Label Grid.Row="3" Grid.Column="1" Content="Errol Flynn"/>
                </Grid>
            </GroupBox>
        </Expander>

The Expander starts out collapsed:

Then shows GroupBox when expanded:

#507 – Expander Control Lets you Expand/Collapse a Set of Controls

You can use an Expander control to hide a set of controls.  When you click on the Expander, the hidden controls are shown.  When you click again, they are hidden again.

The Expander control is a ContentControl, so contains a single child element.  This is typically a panel control, so that you can then include multiple controls in the panel.

    <StackPanel>
        <Expander Header="Goals" Margin="10" >
            <StackPanel Orientation="Vertical">
                <CheckBox Content="Read Ulysses"/>
                <CheckBox Content="Visit Bruges"/>
                <CheckBox Content="Take out the trash"/>
            </StackPanel>
        </Expander>
        <Label Content="Next guy in vertical StackPanel is down here"/>
    </StackPanel>

Notice that when the Expander is expanded, it takes up more room in the container (a StackPanel in this example) and other child elements are shifted.