xamlexpanderwinui-3

How to place expander chevron on the left?


By default the expander chevron is placed on the right:

Expander header with chevron on the right

<Expander
     Header="This text is in the header"
     Content="This is in the content"/>

How can I make the chevron be on the left of the header text?

Looking at the Expander class docs I wasn't able to find promising ExpanderChevron styles.

Looking at the Live Visual Tree I can see the chevron is in the second column of a grid. I looked at trying to override the column via a style, but couldn't figure it out.

Live visual tree of xaml structure


Solution

  • You have two options.

    The first option is to create a custom template. You could copy the default template for the ToggleButton from GitHub and edit as per your requirements.

    The second option is to create your own custom Expander control that extends the existing one and programmatically move the elements:

    public class CustomExpander : Expander
    {
        protected override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
    
            ToggleButton tb = GetTemplateChild("ExpanderHeader") as ToggleButton;
            if (tb != null)
                tb.Loaded += TbLoaded;
        }
    
        private void TbLoaded(object sender, RoutedEventArgs e)
        {
            ToggleButton tb = (ToggleButton)sender;
            tb.Padding = new Thickness(0, 0, 16, 0);
            tb.Loaded -= TbLoaded;
            ContentPresenter cp = FindVisualChild<ContentPresenter>(tb);
            Border border = FindVisualChild<Border>(tb);
            if (cp != null && border != null)
            {
                Grid.SetColumn(cp, 1);
                Grid.SetColumn(border, 0);
                border.Margin = new Thickness(8, 0, 20, 0);
            }
        }
    
        private static T FindVisualChild<T>(DependencyObject visual) where T : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(visual); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(visual, i);
                if (child != null)
                {
                    T correctlyTyped = child as T;
                    if (correctlyTyped != null)
                        return correctlyTyped;
    
                    T descendent = FindVisualChild<T>(child);
                    if (descendent != null)
                        return descendent;
                }
            }
    
            return null;
        }
    }
    

    Don't forget to update your XAML markup to use your custom control:

    <local:CustomExpander Header="This text is in the header" Content="This is in the content" />