Skip to content

Commit 184c79a

Browse files
committed
Show selected item when combobox uses classic mode
-Rename Default to Classic -Make ComboBoxPopup as internal, because it isn't a part of public api -Show selected item when a combobox uses classic mode -Add PopupPlacement property in comboboxpopup
1 parent 09330c6 commit 184c79a

File tree

2 files changed

+100
-23
lines changed

2 files changed

+100
-23
lines changed

MaterialDesignThemes.Wpf/ComboBoxPopup.cs

Lines changed: 93 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,18 @@
1010

1111
namespace MaterialDesignThemes.Wpf
1212
{
13-
public class ComboBoxPopup : Popup
13+
internal enum ComboBoxPopupPlacement
1414
{
15+
Undefined,
16+
Down,
17+
Up,
18+
Classic
19+
}
20+
21+
internal class ComboBoxPopup : Popup
22+
{
23+
#region UpContentTemplate property
24+
1525
public static readonly DependencyProperty UpContentTemplateProperty
1626
= DependencyProperty.Register(nameof(UpContentTemplate),
1727
typeof(ControlTemplate),
@@ -24,6 +34,10 @@ public ControlTemplate UpContentTemplate
2434
set { SetValue(UpContentTemplateProperty, value); }
2535
}
2636

37+
#endregion
38+
39+
#region DownContentTemplate region
40+
2741
public static readonly DependencyProperty DownContentTemplateProperty
2842
= DependencyProperty.Register(nameof(DownContentTemplate),
2943
typeof(ControlTemplate),
@@ -36,18 +50,26 @@ public ControlTemplate DownContentTemplate
3650
set { SetValue(DownContentTemplateProperty, value); }
3751
}
3852

39-
public static readonly DependencyProperty DefaultContentTemplateProperty
40-
= DependencyProperty.Register(nameof(DefaultContentTemplate),
53+
#endregion
54+
55+
#region ClassicContentTemplate property
56+
57+
public static readonly DependencyProperty ClassicContentTemplateProperty
58+
= DependencyProperty.Register(nameof(ClassicContentTemplate),
4159
typeof(ControlTemplate),
4260
typeof(ComboBoxPopup),
4361
new UIPropertyMetadata(null));
4462

45-
public ControlTemplate DefaultContentTemplate
63+
public ControlTemplate ClassicContentTemplate
4664
{
47-
get { return (ControlTemplate)GetValue(DefaultContentTemplateProperty); }
48-
set { SetValue(DefaultContentTemplateProperty, value); }
65+
get { return (ControlTemplate)GetValue(ClassicContentTemplateProperty); }
66+
set { SetValue(ClassicContentTemplateProperty, value); }
4967
}
5068

69+
#endregion
70+
71+
#region UpVerticalOffset property
72+
5173
public static readonly DependencyProperty UpVerticalOffsetProperty
5274
= DependencyProperty.Register(nameof(UpVerticalOffset),
5375
typeof(double),
@@ -60,6 +82,10 @@ public double UpVerticalOffset
6082
set { SetValue(UpVerticalOffsetProperty, value); }
6183
}
6284

85+
#endregion
86+
87+
#region DownVerticalOffset property
88+
6389
public static readonly DependencyProperty DownVerticalOffsetProperty
6490
= DependencyProperty.Register(nameof(DownVerticalOffset),
6591
typeof(double),
@@ -72,6 +98,24 @@ public double DownVerticalOffset
7298
set { SetValue(DownVerticalOffsetProperty, value); }
7399
}
74100

101+
#endregion
102+
103+
#region PopupPlacement property
104+
105+
public static readonly DependencyProperty PopupPlacementProperty
106+
= DependencyProperty.Register(nameof(PopupPlacement),
107+
typeof(ComboBoxPopupPlacement),
108+
typeof(ComboBoxPopup),
109+
new PropertyMetadata(ComboBoxPopupPlacement.Undefined, PopupPlacementPropertyChangedCallback));
110+
111+
public ComboBoxPopupPlacement PopupPlacement
112+
{
113+
get { return (ComboBoxPopupPlacement)GetValue(PopupPlacementProperty); }
114+
set { SetValue(PopupPlacementProperty, value); }
115+
}
116+
117+
#endregion
118+
75119
#region Background property
76120

77121
private static readonly DependencyPropertyKey BackgroundPropertyKey =
@@ -127,17 +171,6 @@ public ComboBoxPopup()
127171
this.CustomPopupPlacementCallback = ComboBoxCustomPopupPlacementCallback;
128172
}
129173

130-
private void SetChildTemplateIfNeed(ControlTemplate template)
131-
{
132-
var contentControl = Child as ContentControl;
133-
if (contentControl == null) throw new InvalidOperationException("Child must be ContentControl");
134-
135-
if (!ReferenceEquals(contentControl.Template, template))
136-
{
137-
contentControl.Template = template;
138-
}
139-
}
140-
141174
private void SetupBackground(IEnumerable<DependencyObject> visualAncestry)
142175
{
143176
var background = visualAncestry
@@ -191,7 +224,7 @@ private CustomPopupPlacement[] ComboBoxCustomPopupPlacementCallback(
191224
if (locationX + popupSize.Width - realOffsetX > screenWidth
192225
|| locationX - realOffsetX < 0)
193226
{
194-
SetChildTemplateIfNeed(DefaultContentTemplate);
227+
PopupPlacement = ComboBoxPopupPlacement.Classic;
195228

196229
var defaultVerticalOffsetIndepent = DpiHelper.TransformToDeviceY(mainVisual, DefaultVerticalOffset);
197230
var newY = locationY + popupSize.Height > screenHeight
@@ -203,7 +236,7 @@ private CustomPopupPlacement[] ComboBoxCustomPopupPlacementCallback(
203236

204237
if (locationY + popupSize.Height > screenHeight)
205238
{
206-
SetChildTemplateIfNeed(UpContentTemplate);
239+
PopupPlacement = ComboBoxPopupPlacement.Up;
207240

208241
var upVerticalOffsetIndepent = DpiHelper.TransformToDeviceY(mainVisual, UpVerticalOffset);
209242
var newY = upVerticalOffsetIndepent - popupSize.Height + targetSize.Height;
@@ -212,13 +245,53 @@ private CustomPopupPlacement[] ComboBoxCustomPopupPlacementCallback(
212245
}
213246
else
214247
{
215-
SetChildTemplateIfNeed(DownContentTemplate);
248+
PopupPlacement = ComboBoxPopupPlacement.Down;
216249

217250
var downVerticalOffsetIndepent = DpiHelper.TransformToDeviceY(mainVisual, DownVerticalOffset);
218251
var newY = downVerticalOffsetIndepent;
219252

220253
return new[] { new CustomPopupPlacement(new Point(offsetX, newY), PopupPrimaryAxis.None) };
221254
}
222255
}
256+
257+
private void SetChildTemplateIfNeed(ControlTemplate template)
258+
{
259+
var contentControl = Child as ContentControl;
260+
if (contentControl == null) throw new InvalidOperationException("Child must be ContentControl");
261+
262+
if (!ReferenceEquals(contentControl.Template, template))
263+
{
264+
contentControl.Template = template;
265+
}
266+
}
267+
268+
private void SetChildTemplate(ComboBoxPopupPlacement placement)
269+
{
270+
switch (placement)
271+
{
272+
case ComboBoxPopupPlacement.Classic:
273+
SetChildTemplateIfNeed(ClassicContentTemplate);
274+
return;
275+
case ComboBoxPopupPlacement.Down:
276+
SetChildTemplateIfNeed(DownContentTemplate);
277+
return;
278+
case ComboBoxPopupPlacement.Up:
279+
SetChildTemplateIfNeed(UpContentTemplate);
280+
return;
281+
default:
282+
throw new NotImplementedException($"Unexpected value {placement} of the {nameof(PopupPlacement)} property inside the {nameof(ComboBoxPopup)} control.");
283+
}
284+
}
285+
286+
private static void PopupPlacementPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
287+
{
288+
var popup = d as ComboBoxPopup;
289+
if (popup == null) return;
290+
291+
if (!(e.NewValue is ComboBoxPopupPlacement)) return;
292+
var placement = (ComboBoxPopupPlacement)e.NewValue;
293+
294+
popup.SetChildTemplate(placement);
295+
}
223296
}
224297
}

MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.ComboBox.xaml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
33
xmlns:converters="clr-namespace:MaterialDesignThemes.Wpf.Converters"
44
xmlns:system="clr-namespace:System;assembly=mscorlib"
5-
xmlns:wpf="clr-namespace:MaterialDesignThemes.Wpf">
5+
xmlns:wpf="clr-namespace:MaterialDesignThemes.Wpf"
6+
xmlns:materialdesign="clr-namespace:MaterialDesignThemes.Wpf">
67

78
<ResourceDictionary.MergedDictionaries>
89
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Shadows.xaml" />
@@ -149,7 +150,7 @@
149150
</Grid>
150151
</ControlTemplate>
151152

152-
<ControlTemplate x:Key="PopupContentDefaultTemplate" TargetType="ContentControl">
153+
<ControlTemplate x:Key="PopupContentClassicTemplate" TargetType="ContentControl">
153154
<Grid MinWidth="{Binding ElementName=templateRoot, Path=ActualWidth, Converter={StaticResource MathAddConverter}, ConverterParameter=32}"
154155
Margin="6">
155156
<Grid.RowDefinitions>
@@ -459,7 +460,7 @@
459460
UpVerticalOffset="15"
460461
UpContentTemplate="{StaticResource PopupContentUpTemplate}"
461462
DownContentTemplate="{StaticResource PopupContentDownTemplate}"
462-
DefaultContentTemplate="{StaticResource PopupContentDefaultTemplate}">
463+
ClassicContentTemplate="{StaticResource PopupContentClassicTemplate}">
463464
<ContentControl>
464465
<ScrollViewer MaxHeight="{TemplateBinding MaxDropDownHeight}"
465466
Background="{Binding Background, ElementName=PART_Popup}">
@@ -470,6 +471,9 @@
470471
</Grid>
471472
</Grid>
472473
<ControlTemplate.Triggers>
474+
<Trigger SourceName="PART_Popup" Property="PopupPlacement" Value="{x:Static materialdesign:ComboBoxPopupPlacement.Classic}">
475+
<Setter Property="ItemContainerStyle" Value="{StaticResource MaterialDesignComboBoxItemStyle}" />
476+
</Trigger>
473477
<Trigger Property="IsEnabled" Value="False">
474478
<Setter TargetName="templateRoot" Property="Opacity" Value="0.56"/>
475479
</Trigger>

0 commit comments

Comments
 (0)