Skip to content

Commit c2c9a04

Browse files
authored
Merge pull request #1336 from Odonno/expanderOrientation
feat(Expander): add ability to change expander orientation
2 parents a7d7831 + e8e878b commit c2c9a04

File tree

15 files changed

+1220
-43
lines changed

15 files changed

+1220
-43
lines changed

Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Expander/ExpanderPage.xaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
HorizontalContentAlignment="Stretch"
1515
Foreground="White"
1616
Background="{Binding Path=BackgroundExpander1.Value, Mode=TwoWay}"
17-
IsExpanded="{Binding Path=IsExpanded1.Value, Mode=TwoWay}">
17+
IsExpanded="{Binding Path=IsExpanded1.Value, Mode=TwoWay}"
18+
ExpandDirection="{Binding Path=ExpandDirection1.Value, Mode=TwoWay}">
1819
<Grid Height="250">
1920
<TextBlock HorizontalAlignment="Center"
2021
TextWrapping="Wrap"
@@ -29,7 +30,8 @@
2930
HorizontalContentAlignment="Stretch"
3031
Foreground="White"
3132
Background="{Binding Path=BackgroundExpander2.Value, Mode=TwoWay}"
32-
IsExpanded="{Binding Path=IsExpanded2.Value, Mode=TwoWay}">
33+
IsExpanded="{Binding Path=IsExpanded2.Value, Mode=TwoWay}"
34+
ExpandDirection="{Binding Path=ExpandDirection2.Value, Mode=TwoWay}">
3335
<Grid Height="250">
3436
<TextBlock HorizontalAlignment="Center"
3537
TextWrapping="Wrap"

Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Expander/ExpanderXaml.bind

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
Header="This is the header - expander 1"
1414
Foreground="White"
1515
Background="@[BackgroundExpander1:Brush:Gray]"
16-
IsExpanded="@[IsExpanded1:Bool:False]">
16+
IsExpanded="@[IsExpanded1:Bool:False]"
17+
ExpandDirection="@[ExpandDirection1:Enum:ExpandDirection.Down]">
1718
<Grid Height="250">
1819
<TextBlock HorizontalAlignment="Center"
1920
TextWrapping="Wrap"
@@ -27,7 +28,8 @@
2728
Header="This is the header - expander 2"
2829
Foreground="White"
2930
Background="@[BackgroundExpander2:Brush:Black]"
30-
IsExpanded="@[IsExpanded2:Bool:True]">
31+
IsExpanded="@[IsExpanded2:Bool:True]"
32+
ExpandDirection="@[ExpandDirection2:Enum:ExpandDirection.Right]">
3133
<Grid Height="250">
3234
<TextBlock HorizontalAlignment="Center"
3335
TextWrapping="Wrap"

Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Menu/MenuPage.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
Orientation="{Binding Orientation.Value, Mode=TwoWay}"
2626
TooltipPlacement="{Binding TooltipPlacement.Value, Mode=TwoWay}">
2727

28-
<controls:MenuItem Name="FileMenu"
28+
<controls:MenuItem x:Name="FileMenu"
2929
controls:Menu.InputGestureText="Alt+F">
3030
<controls:MenuItem.Header>
3131
<StackPanel Orientation="Horizontal">
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// ******************************************************************
2+
// Copyright (c) Microsoft. All rights reserved.
3+
// This code is licensed under the MIT License (MIT).
4+
// THE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
5+
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
7+
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
8+
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
9+
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
10+
// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE.
11+
// ******************************************************************
12+
13+
namespace Microsoft.Toolkit.Uwp.UI.Controls
14+
{
15+
public enum ExpandDirection
16+
{
17+
/// <summary>
18+
/// Down
19+
/// </summary>
20+
Down,
21+
22+
/// <summary>
23+
/// Up
24+
/// </summary>
25+
Up,
26+
27+
/// <summary>
28+
/// Left
29+
/// </summary>
30+
Left,
31+
32+
/// <summary>
33+
/// Right
34+
/// </summary>
35+
Right
36+
}
37+
}

Microsoft.Toolkit.Uwp.UI.Controls/Expander/Expander.Constants.cs

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,61 @@ public partial class Expander
2020
/// <summary>
2121
/// Key of the VisualStateGroup that open/close content
2222
/// </summary>
23-
public const string GroupContent = "ExpandedStates";
23+
private const string ExpandedGroupStateContent = "ExpandedStates";
2424

2525
/// <summary>
2626
/// Key of the VisualState when content is expanded
2727
/// </summary>
28-
public const string StateContentExpanded = "Expanded";
28+
private const string StateContentExpanded = "Expanded";
2929

3030
/// <summary>
3131
/// Key of the VisualState when content is collapsed
3232
/// </summary>
33-
public const string StateContentCollapsed = "Collapsed";
33+
private const string StateContentCollapsed = "Collapsed";
3434

3535
/// <summary>
3636
/// Key of the UI Element that toggle IsExpanded property
3737
/// </summary>
38-
public const string ExpanderToggleButtonPart = "PART_ExpanderToggleButton";
38+
private const string ExpanderToggleButtonPart = "PART_ExpanderToggleButton";
3939

4040
/// <summary>
4141
/// Key of the UI Element that contains the content of the control that is expanded/collapsed
4242
/// </summary>
43-
public const string MainContentPart = "PART_MainContent";
43+
private const string MainContentPart = "PART_MainContent";
44+
45+
/// <summary>
46+
/// Key of the VisualStateGroup that set expander direction of the control
47+
/// </summary>
48+
private const string ExpandDirectionGroupStateContent = "ExpandDirectionStates";
49+
50+
/// <summary>
51+
/// Key of the VisualState when expander direction is set to Left
52+
/// </summary>
53+
private const string StateContentLeftDirection = "LeftDirection";
54+
55+
/// <summary>
56+
/// Key of the VisualState when expander direction is set to Down
57+
/// </summary>
58+
private const string StateContentDownDirection = "DownDirection";
59+
60+
/// <summary>
61+
/// Key of the VisualState when expander direction is set to Right
62+
/// </summary>
63+
private const string StateContentRightDirection = "RightDirection";
64+
65+
/// <summary>
66+
/// Key of the VisualState when expander direction is set to Up
67+
/// </summary>
68+
private const string StateContentUpDirection = "UpDirection";
69+
70+
/// <summary>
71+
/// Key of the UI Element that contains the content of the entire control
72+
/// </summary>
73+
private const string RootGridPart = "PART_RootGrid";
74+
75+
/// <summary>
76+
/// Key of the UI Element that contains the content of the LayoutTransformer (of the expander button)
77+
/// </summary>
78+
private const string LayoutTransformerPart = "PART_LayoutTransformer";
4479
}
4580
}

Microsoft.Toolkit.Uwp.UI.Controls/Expander/Expander.Properties.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ public partial class Expander
3737
public static readonly DependencyProperty IsExpandedProperty =
3838
DependencyProperty.Register(nameof(IsExpanded), typeof(bool), typeof(Expander), new PropertyMetadata(false, OnIsExpandedPropertyChanged));
3939

40+
/// <summary>
41+
/// Identifies the <see cref="ExpandDirection"/> dependency property.
42+
/// </summary>
43+
public static readonly DependencyProperty ExpandDirectionProperty =
44+
DependencyProperty.Register(nameof(ExpandDirection), typeof(ExpandDirection), typeof(Expander), new PropertyMetadata(ExpandDirection.Down, OnExpandDirectionChanged));
45+
4046
/// <summary>
4147
/// Gets or sets a value indicating whether the Header of the control.
4248
/// </summary>
@@ -64,6 +70,15 @@ public bool IsExpanded
6470
set { SetValue(IsExpandedProperty, value); }
6571
}
6672

73+
/// <summary>
74+
/// Gets or sets a value indicating whether the Expand Direction of the control.
75+
/// </summary>
76+
public ExpandDirection ExpandDirection
77+
{
78+
get { return (ExpandDirection)GetValue(ExpandDirectionProperty); }
79+
set { SetValue(ExpandDirectionProperty, value); }
80+
}
81+
6782
private static void OnIsExpandedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
6883
{
6984
var expander = d as Expander;
@@ -78,5 +93,17 @@ private static void OnIsExpandedPropertyChanged(DependencyObject d, DependencyPr
7893
expander.CollapseControl();
7994
}
8095
}
96+
97+
private static void OnExpandDirectionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
98+
{
99+
var expander = d as Expander;
100+
var previousExpandDirection = (ExpandDirection)e.OldValue;
101+
var newExpandDirection = (ExpandDirection)e.NewValue;
102+
103+
if (previousExpandDirection != newExpandDirection)
104+
{
105+
expander.OnExpandDirectionChanged();
106+
}
107+
}
81108
}
82109
}

Microsoft.Toolkit.Uwp.UI.Controls/Expander/Expander.cs

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,15 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
2222
/// <summary>
2323
/// The <see cref="Expander"/> control allows user to show/hide content based on a boolean state
2424
/// </summary>
25-
[TemplateVisualState(Name = StateContentExpanded, GroupName = GroupContent)]
26-
[TemplateVisualState(Name = StateContentCollapsed, GroupName = GroupContent)]
25+
[TemplateVisualState(Name = StateContentExpanded, GroupName = ExpandedGroupStateContent)]
26+
[TemplateVisualState(Name = StateContentCollapsed, GroupName = ExpandedGroupStateContent)]
27+
[TemplateVisualState(Name = StateContentLeftDirection, GroupName = ExpandDirectionGroupStateContent)]
28+
[TemplateVisualState(Name = StateContentDownDirection, GroupName = ExpandDirectionGroupStateContent)]
29+
[TemplateVisualState(Name = StateContentRightDirection, GroupName = ExpandDirectionGroupStateContent)]
30+
[TemplateVisualState(Name = StateContentUpDirection, GroupName = ExpandDirectionGroupStateContent)]
31+
[TemplatePart(Name = RootGridPart, Type = typeof(Grid))]
2732
[TemplatePart(Name = ExpanderToggleButtonPart, Type = typeof(ToggleButton))]
33+
[TemplatePart(Name = LayoutTransformerPart, Type = typeof(LayoutTransformControl))]
2834
[ContentProperty(Name = "Content")]
2935
public partial class Expander : ContentControl
3036
{
@@ -49,6 +55,8 @@ protected override void OnApplyTemplate()
4955
button.KeyDown -= ExpanderToggleButtonPart_KeyDown;
5056
button.KeyDown += ExpanderToggleButtonPart_KeyDown;
5157
}
58+
59+
OnExpandDirectionChanged();
5260
}
5361

5462
protected virtual void OnExpanded(EventArgs args)
@@ -91,5 +99,42 @@ private void CollapseControl()
9199
VisualStateManager.GoToState(this, StateContentCollapsed, true);
92100
OnCollapsed(EventArgs.Empty);
93101
}
102+
103+
public void OnExpandDirectionChanged()
104+
{
105+
var button = (ToggleButton)GetTemplateChild(ExpanderToggleButtonPart);
106+
107+
if (button == null)
108+
{
109+
return;
110+
}
111+
112+
switch (ExpandDirection)
113+
{
114+
case ExpandDirection.Left:
115+
VisualStateManager.GoToState(this, StateContentLeftDirection, true);
116+
VisualStateManager.GoToState(button, StateContentLeftDirection, true);
117+
break;
118+
case ExpandDirection.Down:
119+
VisualStateManager.GoToState(this, StateContentDownDirection, true);
120+
VisualStateManager.GoToState(button, StateContentDownDirection, true);
121+
break;
122+
case ExpandDirection.Right:
123+
VisualStateManager.GoToState(this, StateContentRightDirection, true);
124+
VisualStateManager.GoToState(button, StateContentRightDirection, true);
125+
break;
126+
case ExpandDirection.Up:
127+
VisualStateManager.GoToState(this, StateContentUpDirection, true);
128+
VisualStateManager.GoToState(button, StateContentUpDirection, true);
129+
break;
130+
}
131+
132+
// Re-execute animation on expander toggle button (to set correct arrow rotation)
133+
VisualStateManager.GoToState(button, "Normal", true);
134+
if (button.IsChecked.HasValue && button.IsChecked.Value)
135+
{
136+
VisualStateManager.GoToState(button, "Checked", true);
137+
}
138+
}
94139
}
95140
}

0 commit comments

Comments
 (0)