Search code examples
c#xamlwindows-phone-7windows-phone-8silverlight-toolkit

Custom header with ExpanderView from Toolkit for Windows Phone


I am using ExpanderView from Toolkit for Windows Phone. What I add is line below each Header. What I can't do is stretch line for Headers which are Expandable.

<toolkit:ExpanderView x:Name="ev" HorizontalAlignment="Stretch" Margin="0,0,0,8" 
                                        Header="{Binding}"
                                        NonExpandableHeader="{Binding}"
                                        Expander="{Binding}"
                                        ItemsSource="{Binding}"
                                        IsNonExpandable="{Binding HasSingleMessage}">

<toolkit:ExpanderView.HeaderTemplate>
    <DataTemplate>
        <StackPanel>
            <TextBlock Text="{Binding LastMessageReceived.Header}"
            HorizontalAlignment="Stretch"  
            Foreground="Black"
            FontSize="{StaticResource PhoneFontSizeLarge}" 
            FontFamily="{StaticResource PhoneFontFamilySemiLight}"/>
            <Rectangle Height="1" StrokeThickness="0" Fill="Black" Margin="0,8" />
        </StackPanel>
    </DataTemplate>
</toolkit:ExpanderView.HeaderTemplate>

Sample screen with red mark


Solution

  • It's a bit tricky to get to the bottom of this. The bottom line is, I think the only way get what you want (stretch the line) is to include a modified version of the control template in your XAML resources, and make the header stretch to fill its container.

    If you check source code at the link, and scroll down to the ExpanderView control template, you will see that the header element is defined like this:

    <ListBoxItem x:Name="ExpandableContent" controls:TiltEffect.IsTiltEnabled="True"
                                         Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Grid.ColumnSpan="2">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="41"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <ContentControl x:Name="Header"
                            HorizontalContentAlignment="Stretch"
                            HorizontalAlignment="Stretch"
                            Content="{TemplateBinding Header}"
                            ContentTemplate="{TemplateBinding HeaderTemplate}"
                            Grid.Row="0" Grid.Column="0"
                            Grid.ColumnSpan="2"/>
            <ContentControl x:Name="Expander"                                            
                            Margin="11,0,0,0"
                            Grid.Row="1" Grid.Column="1"
                            HorizontalContentAlignment="Stretch"
                            HorizontalAlignment="Stretch"
                            Content="{TemplateBinding Expander}"
                            ContentTemplate="{TemplateBinding ExpanderTemplate}"/>
            <Grid x:Name="ExpanderPanel" Grid.Row="0" Grid.Column="0" 
                  Grid.RowSpan="2" Grid.ColumnSpan="2" Background="Transparent"/>
        </Grid>
    </ListBoxItem>
    

    Now, at first glance this looks fine, because the "Header" ContentControl has both HorizontalAlignment and HorizontalContentAlignment set to "Stretch". Unfortunately, the parent ListBoxItem does not define its HorizontalContentAlignment, whose default may not be "Stretch". (I'm uncertain on this point because the MSDN documentation does not list the default -- but the default for the corresponding property is "Left" in WPF and "Center" in Silverlight.)

    So I would try copying the default control template into your application resources, and add the appropriate alignments to the "ExpandableContent" ListBoxItem:

    <ListBoxItem x:Name="ExpandableContent" 
                 HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" ...