I'm trying to style an Avalonia Expander control but I'm unable to fully figure out how to style the header. My main difficulty is styling the chevron button. I'm not sure quite what you call it, but I've marked it on this image to show what I mean on an unstyled control.
The code I have for my own control looks like this (ignore the wild colours, that was so I could easily distinguish different parts of the control easily while experimenting):
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:ExpanderApp.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="ExpanderApp.Views.MainWindow"
x:DataType="vm:MainWindowViewModel">
<Design.DataContext>
<!-- This only sets the DataContext for the previewer in an IDE,
to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
<vm:MainWindowViewModel/>
</Design.DataContext>
<Window.Styles>
<Style Selector="Expander">
<!-- The margin around the outside of the whole control. -->
<Setter Property="Margin" Value="10"/>
<!-- These are the styles of the main content of the expander -->
<Setter Property="Background" Value="Blue"/>
<Setter Property="Foreground" Value="Yellow"/>
<Setter Property="Padding" Value="20"/>
<!-- The toggle button is the entire header control -->
<Style Selector="^ /template/ ToggleButton">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="DarkBlue"/>
<Setter Property="Padding" Value="10"/>
</Style>
<!-- The style of the header when the mouse pointer is over it -->
<Style Selector="^ /template/ ToggleButton:pointerover /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Foreground" Value="White"/>
</Style>
<Style Selector="^ /template/ ToggleButton /template/ Border:pointerover">
<Setter Property="Background" Value="BlueViolet"/>
</Style>
<!-- The header style when contracted -->
<Style Selector="^ /template/ ToggleButton:unchecked">
<Setter Property="Background" Value="DeepSkyBlue"/>
</Style>
<!-- Style the chevron icon itself -->
<Style Selector="^ /template/ ToggleButton /template/ Path#ExpanderChevron">
<Setter Property="Fill" Value="Yellow"/>
</Style>
</Style>
</Window.Styles>
<Expander IsExpanded="true">
<Expander.Header>
<Label>This is the header</Label>
</Expander.Header>
<StackPanel Orientation="Vertical">
<Label Name="First">This is the first label of the expander</Label>
<Label Name="Second">This is the second label of the expander</Label>
<Label Name="Third">This is the third label of the expander</Label>
<Label Name="Fourth">This is the fourth label of the expander</Label>
</StackPanel>
</Expander>
</Window>
So, how do I style this square "chevron button"? Everything I've tried or found has not worked or I don't understand how to extrapolate the information given to my situation (a lot of answers just point at the source code for the control, which I can't map between that and what I need to do to style it in my code).
I want to change the colour of the button and the chevron when displaying normally, when hovered over and when expanded.
Also, if there is anything about the way I've used the existing styles that could be improved on I'm happy to take advice on that too.
here is a working example of exactly what you said: changing the styles of the header button, chevron bg color and the chevron icon:
<Window.Styles>
<!-- Chevron Button Normal State -->
<Style Selector="Expander /template/ ToggleButton:not(:pointerover):not(:pressed) /template/ Border#ExpandCollapseChevronBorder">
<Setter Property="Background" Value="SaddleBrown" />
<Setter Property="BorderBrush" Value="White" />
</Style>
<!-- Chevron Icon Normal State -->
<Style Selector="Expander /template/ ToggleButton:not(:pointerover):not(:pressed) /template/ Path#ExpandCollapseChevron">
<Setter Property="Stroke" Value="White" />
</Style>
<!-- Chevron Button Hover State -->
<Style Selector="Expander /template/ ToggleButton:pointerover /template/ Border#ExpandCollapseChevronBorder">
<Setter Property="Background" Value="DeepPink" />
<Setter Property="BorderBrush" Value="Yellow" />
</Style>
<!-- Chevron Icon Hover State -->
<Style Selector="Expander /template/ ToggleButton:pointerover /template/ Path#ExpandCollapseChevron">
<Setter Property="Stroke" Value="Yellow" />
</Style>
<!-- Chevron Button Pressed State -->
<Style Selector="Expander /template/ ToggleButton:pressed /template/ Border#ExpandCollapseChevronBorder">
<Setter Property="Background" Value="Red" />
<Setter Property="BorderBrush" Value="Orange" />
</Style>
<!-- Chevron Icon Pressed State -->
<Style Selector="Expander /template/ ToggleButton:pressed /template/ Path#ExpandCollapseChevron">
<Setter Property="Stroke" Value="Orange" />
</Style>
<!-- Chevron Button Expanded State -->
<Style Selector="Expander:expanded /template/ ToggleButton:not(:pointerover):not(:pressed) /template/ Border#ExpandCollapseChevronBorder">
<Setter Property="Background" Value="ForestGreen" />
<Setter Property="BorderBrush" Value="White" />
</Style>
<!-- Chevron Icon Expanded State -->
<Style Selector="Expander:expanded /template/ ToggleButton:not(:pointerover):not(:pressed) /template/ Path#ExpandCollapseChevron">
<Setter Property="Stroke" Value="White" />
</Style>
<!-- Chevron Button Expanded + Hover -->
<Style Selector="Expander:expanded /template/ ToggleButton:pointerover /template/ Border#ExpandCollapseChevronBorder">
<Setter Property="Background" Value="LimeGreen" />
</Style>
<!-- Chevron Icon Expanded + Hover -->
<Style Selector="Expander:expanded /template/ ToggleButton:pointerover /template/ Path#ExpandCollapseChevron">
<Setter Property="Stroke" Value="Yellow" />
</Style>
<!-- Chevron Button Expanded + Pressed -->
<Style Selector="Expander:expanded /template/ ToggleButton:pressed /template/ Border#ExpandCollapseChevronBorder">
<Setter Property="Background" Value="DarkGreen" />
</Style>
<!-- Chevron Icon Expanded + Pressed -->
<Style Selector="Expander:expanded /template/ ToggleButton:pressed /template/ Path#ExpandCollapseChevron">
<Setter Property="Stroke" Value="Orange" />
</Style>
<!-- header style -->
<!-- Header Button Normal State -->
<Style Selector="Expander /template/ ToggleButton">
<Setter Property="Background" Value="DarkBlue" />
<Setter Property="Foreground" Value="White" />
<Setter Property="BorderBrush" Value="Navy" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Padding" Value="15,10" />
</Style>
<!-- Header Button Hover State -->
<Style Selector="Expander /template/ ToggleButton:pointerover /template/ Border#ToggleButtonBackground">
<Setter Property="Background" Value="BlueViolet" />
<Setter Property="BorderBrush" Value="Purple" />
</Style>
<!-- Header Button Pressed State -->
<Style Selector="Expander /template/ ToggleButton:pressed /template/ Border#ToggleButtonBackground">
<Setter Property="Background" Value="DarkViolet" />
<Setter Property="BorderBrush" Value="DarkOrchid" />
</Style>
<!-- Header Button Expanded State -->
<Style Selector="Expander:expanded /template/ ToggleButton">
<Setter Property="Background" Value="MidnightBlue" />
<Setter Property="BorderBrush" Value="RoyalBlue" />
</Style>
<!-- Header Button Expanded + Hover -->
<Style Selector="Expander:expanded /template/ ToggleButton:pointerover /template/ Border#ToggleButtonBackground">
<Setter Property="Background" Value="MediumSlateBlue" />
<Setter Property="BorderBrush" Value="DodgerBlue" />
</Style>
<!-- Header Button Expanded + Pressed -->
<Style Selector="Expander:expanded /template/ ToggleButton:pressed /template/ Border#ToggleButtonBackground">
<Setter Property="Background" Value="DarkSlateBlue" />
<Setter Property="BorderBrush" Value="SteelBlue" />
</Style>
</Window.Styles>
<StackPanel Margin="20" Spacing="10">
<Expander IsExpanded="true">
<Expander.Header>
<TextBlock
FontSize="14"
Foreground="White"
Text="This is the header" />
</Expander.Header>
<StackPanel Orientation="Vertical" Spacing="5">
<TextBlock Text="This is the first label of the expander" />
<TextBlock Text="This is the second label of the expander" />
<TextBlock Text="This is the third label of the expander" />
<TextBlock Text="This is the fourth label of the expander" />
</StackPanel>
</Expander>
</StackPanel>
Notes:
1- Styling an Expander in Avalonia involves understanding its template structure. The Expander has two main parts you'll want to style:
a- The Header Button: This is the entire clickable area that contains your header content and the chevron.
b- The Chevron Button: This is the small square containing the arrow icon that you highlighted which is actually the Border element. It has two parts too:
b.1- The button background (Border#ExpandCollapseChevronBorder)
b.2- The arrow icon (Path#ExpandCollapseChevron)
2- Follow the template hierarchy: Expander /template/ ToggleButton /template/ Elementname.
Expander /template/ ToggleButton[state] /template/ Path#ExpandCollapseChevron
3- You're trying to style elements that don't exist in the template hierarchy you're targeting, You're using ExpanderChevron but the actual name is ExpandCollapseChevron .
4- The normal state styles are being overridden by the default theme. You need to add :not(:pointerover):not(:pressed) to your normal state selector to make it more specific.
5- Use Stroke not Fill for the chevron icon because it's an outline not a filled shape.
I hope this helps, good luck