WPF: Expander.Header - dock control right

88 views Asked by At

I want the red button in the expander header to be docked right. How can I do this? enter image description here

<StackPanel Orientation="Vertical" x:Name="spTest" Margin="10">
    <Border BorderBrush="Black" BorderThickness="1">
        <Expander Margin="5,0,5,0">
            <Expander.Header>
                <Grid Margin="5,0,0,0" HorizontalAlignment="Stretch">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="40"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="TEXT1 1231521312"  Grid.Column="0" FontSize="18" Foreground="Black" VerticalAlignment="Center" HorizontalAlignment="Stretch"/>
                    <TextBlock Grid.Column="1" FontSize="18" FontStyle="Italic" Margin="10,0,10,0" Foreground="Black" VerticalAlignment="Center" Text="Text2"/>
                    <Button x:Name="btnRemove" Grid.Column="2" Width="40" Height="40" Background="#F8CECC" Content="X" FontWeight="Normal" FontSize="18" BorderBrush="#B95753"/>
                </Grid>
            </Expander.Header>
        </Expander>
    </Border>
</StackPanel>

Thank you!!

1

There are 1 answers

1
Rekshino On BEST ANSWER

The issue comes from ContentPresenter used for header in default template. ContentPresenter has it's HorizontalAlignment set not to the Stretch. To change it you could try to bind HorizontalAlignment of the Grid to the HorizontalAlignment of the ContentPresenter.

<StackPanel Orientation="Vertical" x:Name="spTest" Margin="10">
    <Border BorderBrush="Black" BorderThickness="1">
        <Expander Margin="5,0,5,0">
            <Expander.Header>
                <Grid Margin="5,0,0,0" 

                    HorizontalAlignment="{Binding HorizontalAlignment, RelativeSource={RelativeSource AncestorType=ContentPresenter}, Mode=OneWayToSource}">

                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="40"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="TEXT1 1231521312"  Grid.Column="0" FontSize="18" Foreground="Black" VerticalAlignment="Center" HorizontalAlignment="Stretch"/>
                    <TextBlock Grid.Column="1" FontSize="18" FontStyle="Italic" Margin="10,0,10,0" Foreground="Black" VerticalAlignment="Center" Text="Text2"/>
                    <Button x:Name="btnRemove" Grid.Column="2" Width="40" Height="40" Background="#F8CECC" Content="X" FontWeight="Normal" FontSize="18" BorderBrush="#B95753"/>
                </Grid>
            </Expander.Header>
        </Expander>
    </Border>
</StackPanel>

Another way, which would work with nested Expander is to set/bind the Grid.Width.

<Grid Margin="5,0,0,0" Width="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType=Expander}, Converter={StaticResource SubtractConverter}, ConverterParameter=5}">

public class SubtractConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return 
            (double)value 
            - 20/*Default template: Grid's column width */ 
            - 4/*Default template: margin of ContentPresenter*/ 
            - 2/*Default template:  2*BorderThikness */ 
            - double.Parse(parameter as string) /*Margin of Grid in Header*/;
    }

    public object ConvertBack(object value, Type targetTypes, object parameter, CultureInfo culture)
    {
        return value;
    }
}

Another way would be override default template for Expander see Expander Styles and Templates.