Skip to content

Commit 1cd75db

Browse files
Add new options to the ExpanderAssist class (#3294)
* Add new options to the ExpanderAssist class: - ExpanderPosition: to set the position of the Expander Icon --> Start: at the start of the header --> End: at the end of the header - CollapsedIcon: to set the icon when the expander is collapsed - ExpandedIcon: to set the icon when the expander is expanded * Combine the two properties Expand&Collapce icon in a single property ExpanderButtonContent. Rename the ExpanderPosition to ExpanderButtonPosition. * Added support for button position on vertical template Added new default button position to support different default for vertical and horizontal. --------- Co-authored-by: Kevin Bost <[email protected]>
1 parent 255dbda commit 1cd75db

File tree

3 files changed

+188
-48
lines changed

3 files changed

+188
-48
lines changed

MainDemo.Wpf/Expander.xaml

Lines changed: 89 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
<Grid.RowDefinitions>
4343
<RowDefinition Height="Auto" />
4444
<RowDefinition Height="Auto" />
45+
<RowDefinition Height="Auto" />
4546
</Grid.RowDefinitions>
4647

4748
<Grid.ColumnDefinitions>
@@ -132,18 +133,71 @@
132133
</materialDesign:Card>
133134
</smtx:XamlDisplay>
134135

136+
<smtx:XamlDisplay Grid.Row="2"
137+
Grid.Column="0"
138+
Margin="4,24,0,0"
139+
UniqueKey="expander_3">
140+
<materialDesign:Card>
141+
<StackPanel>
142+
<Expander HorizontalAlignment="Stretch" Header="Expander Example 3a">
143+
<Expander.Style>
144+
<Style TargetType="Expander" BasedOn="{StaticResource MaterialDesignExpander}">
145+
<Setter Property="materialDesign:ExpanderAssist.ExpanderButtonContent" Value="{materialDesign:PackIcon Kind=Plus}" />
146+
<Style.Triggers>
147+
<Trigger Property="IsExpanded" Value="True">
148+
<Setter Property="materialDesign:ExpanderAssist.ExpanderButtonContent" Value="{materialDesign:PackIcon Kind=Minus}" />
149+
</Trigger>
150+
</Style.Triggers>
151+
</Style>
152+
</Expander.Style>
153+
<StackPanel Margin="24,8,24,16"
154+
Orientation="Vertical"
155+
TextBlock.Foreground="{DynamicResource MaterialDesignBody}">
156+
<TextBlock Text="Your Content" />
157+
<TextBlock Style="{StaticResource HorizontalExpanderContentTextBlock}" />
158+
</StackPanel>
159+
</Expander>
160+
161+
<Border Style="{StaticResource HorizontalDividerBorder}" />
162+
163+
<Expander HorizontalAlignment="Stretch"
164+
materialDesign:ExpanderAssist.ExpanderButtonPosition="Start">
165+
<Expander.Header>
166+
<TextBlock Text="Expander Example 3b" Margin="10,0,0,0" />
167+
</Expander.Header>
168+
<StackPanel Margin="24,8,24,16"
169+
Orientation="Vertical"
170+
TextBlock.Foreground="{DynamicResource MaterialDesignBody}">
171+
<TextBlock Text="Your Content" />
172+
<TextBlock Style="{StaticResource HorizontalExpanderContentTextBlock}" />
173+
</StackPanel>
174+
</Expander>
175+
176+
<Border Style="{StaticResource HorizontalDividerBorder}" />
177+
178+
<Expander HorizontalAlignment="Stretch" Header="Expander Example 3b" materialDesign:ExpanderAssist.ExpanderButtonPosition="End">
179+
<StackPanel Margin="24,8,24,16"
180+
Orientation="Vertical"
181+
TextBlock.Foreground="{DynamicResource MaterialDesignBody}">
182+
<TextBlock Text="Your Content" />
183+
<TextBlock Style="{StaticResource HorizontalExpanderContentTextBlock}" />
184+
</StackPanel>
185+
</Expander>
186+
</StackPanel>
187+
</materialDesign:Card>
188+
</smtx:XamlDisplay>
135189

136190
<smtx:XamlDisplay Grid.Row="0"
137-
Grid.RowSpan="2"
191+
Grid.RowSpan="3"
138192
Grid.Column="1"
139193
Margin="8"
140194
HorizontalAlignment="Left"
141195
VerticalAlignment="Stretch"
142-
UniqueKey="expander_3">
196+
UniqueKey="expander_4">
143197
<StackPanel Orientation="Horizontal">
144198
<Expander ExpandDirection="Left">
145199
<Expander.Header>
146-
<TextBlock RenderTransformOrigin=".5,.5" Text="Expander Example 3a">
200+
<TextBlock RenderTransformOrigin=".5,.5" Text="Expander Example 4a">
147201
<TextBlock.LayoutTransform>
148202
<RotateTransform Angle="90" />
149203
</TextBlock.LayoutTransform>
@@ -162,7 +216,7 @@
162216

163217
<Expander ExpandDirection="Right">
164218
<Expander.Header>
165-
<TextBlock RenderTransformOrigin=".5,.5" Text="Expander Example 3b">
219+
<TextBlock RenderTransformOrigin=".5,.5" Text="Expander Example 4b">
166220
<TextBlock.LayoutTransform>
167221
<RotateTransform Angle="90" />
168222
</TextBlock.LayoutTransform>
@@ -179,9 +233,9 @@
179233

180234
<Border Style="{StaticResource VerticalDividerBorder}" />
181235

182-
<Expander ExpandDirection="Right">
236+
<Expander ExpandDirection="Right" materialDesign:ExpanderAssist.ExpanderButtonPosition="End">
183237
<Expander.Header>
184-
<TextBlock RenderTransformOrigin=".5,.5" Text="Expander Example 3c">
238+
<TextBlock RenderTransformOrigin=".5,.5" Text="Expander Example 4c">
185239
<TextBlock.LayoutTransform>
186240
<RotateTransform Angle="90" />
187241
</TextBlock.LayoutTransform>
@@ -198,6 +252,35 @@
198252

199253
<Border Style="{StaticResource VerticalDividerBorder}" />
200254

255+
<Expander ExpandDirection="Right" materialDesign:ExpanderAssist.ExpanderButtonPosition="Start">
256+
<Expander.Style>
257+
<Style TargetType="Expander" BasedOn="{StaticResource MaterialDesignExpander}">
258+
<Setter Property="materialDesign:ExpanderAssist.ExpanderButtonContent" Value="{materialDesign:PackIcon Kind=Plus}" />
259+
<Style.Triggers>
260+
<Trigger Property="IsExpanded" Value="True">
261+
<Setter Property="materialDesign:ExpanderAssist.ExpanderButtonContent" Value="{materialDesign:PackIcon Kind=Minus}" />
262+
</Trigger>
263+
</Style.Triggers>
264+
</Style>
265+
</Expander.Style>
266+
<Expander.Header>
267+
<TextBlock RenderTransformOrigin=".5,.5" Text="Expander Example 4d" HorizontalAlignment="Left">
268+
<TextBlock.LayoutTransform>
269+
<RotateTransform Angle="90" />
270+
</TextBlock.LayoutTransform>
271+
</TextBlock>
272+
</Expander.Header>
273+
274+
<StackPanel Margin="8,24,16,24"
275+
Orientation="Vertical"
276+
TextBlock.Foreground="{DynamicResource MaterialDesignBody}">
277+
<TextBlock Text="Your Content" />
278+
<TextBlock Style="{StaticResource VerticalExpanderContentTextBlock}" />
279+
</StackPanel>
280+
</Expander>
281+
282+
<Border Style="{StaticResource VerticalDividerBorder}" />
283+
201284
<Expander materialDesign:ExpanderAssist.VerticalHeaderPadding="0,35,0,5" ExpandDirection="Right">
202285
<Expander.Header>
203286
<TextBlock RenderTransformOrigin=".5,.5" Text="Custom Header Padding">

MaterialDesignThemes.Wpf/ExpanderAssist.cs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,17 @@
22

33
namespace MaterialDesignThemes.Wpf;
44

5+
public enum ExpanderButtonPosition
6+
{
7+
Default,
8+
Start,
9+
End
10+
}
11+
512
public static class ExpanderAssist
613
{
7-
private static readonly Thickness DefaultHorizontalHeaderPadding = new Thickness(24, 12, 24, 12);
8-
private static readonly Thickness DefaultVerticalHeaderPadding = new Thickness(12, 24, 12, 24);
14+
private static readonly Thickness DefaultHorizontalHeaderPadding = new(24, 12, 24, 12);
15+
private static readonly Thickness DefaultVerticalHeaderPadding = new(12, 24, 12, 24);
916

1017
#region AttachedProperty : HorizontalHeaderPaddingProperty
1118
public static readonly DependencyProperty HorizontalHeaderPaddingProperty
@@ -49,4 +56,24 @@ public static readonly DependencyProperty HeaderBackgroundProperty
4956
public static void SetHeaderBackground(Expander element, Brush? value)
5057
=> element.SetValue(HeaderBackgroundProperty, value);
5158
#endregion
59+
60+
#region AttachedProperty : ExpanderButtonContentProperty
61+
public static readonly DependencyProperty ExpanderButtonContentProperty
62+
= DependencyProperty.RegisterAttached("ExpanderButtonContent", typeof(object), typeof(ExpanderAssist));
63+
64+
public static object? GetExpanderButtonContent(Expander element)
65+
=> (object?)element.GetValue(ExpanderButtonContentProperty);
66+
public static void SetExpanderButtonContent(Expander element, object? value)
67+
=> element.SetValue(ExpanderButtonContentProperty, value);
68+
#endregion
69+
70+
#region AttachedProperty : ExpanderButtonPositionProperty
71+
public static readonly DependencyProperty ExpanderButtonPositionProperty
72+
= DependencyProperty.RegisterAttached("ExpanderButtonPosition", typeof(ExpanderButtonPosition), typeof(ExpanderAssist), new PropertyMetadata(ExpanderButtonPosition.Default));
73+
74+
public static ExpanderButtonPosition GetExpanderButtonPosition(Expander element)
75+
=> (ExpanderButtonPosition)element.GetValue(ExpanderButtonPositionProperty);
76+
public static void SetExpanderButtonPosition(Expander element, ExpanderButtonPosition value)
77+
=> element.SetValue(ExpanderButtonPositionProperty, value);
78+
#endregion
5279
}

MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.Expander.xaml

Lines changed: 70 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -12,41 +12,52 @@
1212
<Style x:Key="MaterialDesignExpanderToggleButton" TargetType="{x:Type ToggleButton}">
1313
<Setter Property="Template">
1414
<Setter.Value>
15-
<ControlTemplate TargetType="{x:Type ToggleButton}">
16-
<Border Background="Transparent">
17-
<VisualStateManager.VisualStateGroups>
18-
<VisualStateGroup x:Name="CheckStates">
19-
<VisualState x:Name="Checked">
20-
<Storyboard>
21-
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ExpandPathRotateTransform" Storyboard.TargetProperty="Angle">
22-
<EasingDoubleKeyFrame KeyTime="{StaticResource ExpandKeyTime}" Value="180" />
23-
</DoubleAnimationUsingKeyFrames>
24-
</Storyboard>
25-
</VisualState>
26-
<VisualState x:Name="Unchecked">
27-
<Storyboard>
28-
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ExpandPathRotateTransform" Storyboard.TargetProperty="Angle">
29-
<EasingDoubleKeyFrame KeyTime="{StaticResource CollapseKeyTime}" Value="0" />
30-
</DoubleAnimationUsingKeyFrames>
31-
</Storyboard>
32-
</VisualState>
33-
</VisualStateGroup>
34-
</VisualStateManager.VisualStateGroups>
35-
<wpf:PackIcon x:Name="ExpandPath"
36-
Width="24"
37-
Height="24"
38-
Foreground="{TemplateBinding Foreground}"
39-
Kind="ChevronDown"
40-
Opacity="0.38"
41-
RenderTransformOrigin="0.5 0.5">
42-
<wpf:PackIcon.RenderTransform>
43-
<RotateTransform x:Name="ExpandPathRotateTransform" />
44-
</wpf:PackIcon.RenderTransform>
45-
</wpf:PackIcon>
46-
</Border>
15+
<ControlTemplate>
16+
<ContentControl Content="{Binding RelativeSource={RelativeSource AncestorType=Expander, Mode=FindAncestor}, Path=(wpf:ExpanderAssist.ExpanderButtonContent)}" />
4717
</ControlTemplate>
4818
</Setter.Value>
4919
</Setter>
20+
<Style.Triggers>
21+
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Expander, Mode=FindAncestor}, Path=(wpf:ExpanderAssist.ExpanderButtonContent)}" Value="{x:Null}">
22+
<Setter Property="Template">
23+
<Setter.Value>
24+
<ControlTemplate TargetType="{x:Type ToggleButton}">
25+
<Border Background="Transparent">
26+
<VisualStateManager.VisualStateGroups>
27+
<VisualStateGroup x:Name="CheckStates">
28+
<VisualState x:Name="Checked">
29+
<Storyboard>
30+
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ExpandPathRotateTransform" Storyboard.TargetProperty="Angle">
31+
<EasingDoubleKeyFrame KeyTime="{StaticResource ExpandKeyTime}" Value="180" />
32+
</DoubleAnimationUsingKeyFrames>
33+
</Storyboard>
34+
</VisualState>
35+
<VisualState x:Name="Unchecked">
36+
<Storyboard>
37+
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ExpandPathRotateTransform" Storyboard.TargetProperty="Angle">
38+
<EasingDoubleKeyFrame KeyTime="{StaticResource CollapseKeyTime}" Value="0" />
39+
</DoubleAnimationUsingKeyFrames>
40+
</Storyboard>
41+
</VisualState>
42+
</VisualStateGroup>
43+
</VisualStateManager.VisualStateGroups>
44+
<wpf:PackIcon x:Name="ExpandPath"
45+
Width="24"
46+
Height="24"
47+
Foreground="{TemplateBinding Foreground}"
48+
Kind="ChevronDown"
49+
Opacity="0.38"
50+
RenderTransformOrigin="0.5 0.5">
51+
<wpf:PackIcon.RenderTransform>
52+
<RotateTransform x:Name="ExpandPathRotateTransform" />
53+
</wpf:PackIcon.RenderTransform>
54+
</wpf:PackIcon>
55+
</Border>
56+
</ControlTemplate>
57+
</Setter.Value>
58+
</Setter>
59+
</DataTrigger>
60+
</Style.Triggers>
5061
</Style>
5162

5263
<Style x:Key="MaterialDesignHorizontalHeaderStyle" TargetType="{x:Type ToggleButton}">
@@ -58,20 +69,20 @@
5869
<Border Padding="{Binding Path=(wpf:ExpanderAssist.HorizontalHeaderPadding), RelativeSource={RelativeSource AncestorType=Expander, AncestorLevel=1}}" Background="{TemplateBinding Background}">
5970
<Grid>
6071
<Grid.ColumnDefinitions>
72+
<ColumnDefinition Width="Auto" />
6173
<ColumnDefinition Width="*" />
62-
<ColumnDefinition Width="16" />
6374
<ColumnDefinition Width="Auto" />
6475
</Grid.ColumnDefinitions>
6576

66-
<ContentPresenter Grid.Column="0"
77+
<ContentPresenter x:Name="ExpanderHeader"
78+
Grid.Column="1"
6779
VerticalAlignment="Center"
6880
Content="{TemplateBinding Content}"
6981
ContentStringFormat="{TemplateBinding ContentStringFormat}"
7082
ContentTemplate="{TemplateBinding ContentTemplate}"
7183
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}" />
7284

7385
<ToggleButton x:Name="ExpanderButton"
74-
Grid.Column="2"
7586
VerticalAlignment="Center"
7687
Foreground="{TemplateBinding Foreground}"
7788
IsChecked="{Binding Path=IsChecked, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
@@ -90,30 +101,38 @@
90101
</Style>
91102
</ToggleButton.Style>
92103
</ToggleButton>
93-
94104
</Grid>
95105
</Border>
106+
<ControlTemplate.Triggers>
107+
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Expander, Mode=FindAncestor}, Path=(wpf:ExpanderAssist.ExpanderButtonPosition)}" Value="Start">
108+
<Setter TargetName="ExpanderButton" Property="Grid.Column" Value="0" />
109+
</DataTrigger>
110+
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Expander, Mode=FindAncestor}, Path=(wpf:ExpanderAssist.ExpanderButtonPosition)}" Value="End">
111+
<Setter TargetName="ExpanderButton" Property="Grid.Column" Value="2" />
112+
</DataTrigger>
113+
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Expander, Mode=FindAncestor}, Path=(wpf:ExpanderAssist.ExpanderButtonPosition)}" Value="Default">
114+
<Setter TargetName="ExpanderButton" Property="Grid.Column" Value="2" />
115+
</DataTrigger>
116+
</ControlTemplate.Triggers>
96117
</ControlTemplate>
97118
</Setter.Value>
98119
</Setter>
99120
</Style>
100121

101122
<Style x:Key="MaterialDesignVerticalHeaderStyle" TargetType="{x:Type ToggleButton}">
102123
<Setter Property="Background" Value="Transparent" />
103-
104124
<Setter Property="Template">
105125
<Setter.Value>
106126
<ControlTemplate TargetType="{x:Type ToggleButton}">
107127
<Border Padding="{Binding Path=(wpf:ExpanderAssist.VerticalHeaderPadding), RelativeSource={RelativeSource AncestorType=Expander, AncestorLevel=1}}" Background="{TemplateBinding Background}">
108128
<Grid>
109129
<Grid.RowDefinitions>
110130
<RowDefinition Height="Auto" />
111-
<RowDefinition Height="16" />
112131
<RowDefinition Height="*" />
132+
<RowDefinition Height="Auto" />
113133
</Grid.RowDefinitions>
114134

115135
<ToggleButton x:Name="ExpanderButton"
116-
Grid.Row="0"
117136
VerticalAlignment="Center"
118137
Foreground="{TemplateBinding Foreground}"
119138
IsChecked="{Binding Path=IsChecked, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
@@ -143,7 +162,7 @@
143162
</ToggleButton.Style>
144163
</ToggleButton>
145164

146-
<ContentPresenter Grid.Row="2"
165+
<ContentPresenter Grid.Row="1"
147166
VerticalAlignment="Center"
148167
Content="{TemplateBinding Content}"
149168
ContentStringFormat="{TemplateBinding ContentStringFormat}"
@@ -152,6 +171,17 @@
152171

153172
</Grid>
154173
</Border>
174+
<ControlTemplate.Triggers>
175+
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Expander, Mode=FindAncestor}, Path=(wpf:ExpanderAssist.ExpanderButtonPosition)}" Value="Start">
176+
<Setter TargetName="ExpanderButton" Property="Grid.Row" Value="0" />
177+
</DataTrigger>
178+
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Expander, Mode=FindAncestor}, Path=(wpf:ExpanderAssist.ExpanderButtonPosition)}" Value="End">
179+
<Setter TargetName="ExpanderButton" Property="Grid.Row" Value="2" />
180+
</DataTrigger>
181+
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Expander, Mode=FindAncestor}, Path=(wpf:ExpanderAssist.ExpanderButtonPosition)}" Value="Default">
182+
<Setter TargetName="ExpanderButton" Property="Grid.Row" Value="0" />
183+
</DataTrigger>
184+
</ControlTemplate.Triggers>
155185
</ControlTemplate>
156186
</Setter.Value>
157187
</Setter>

0 commit comments

Comments
 (0)