10
10
11
11
namespace MaterialDesignThemes . Wpf
12
12
{
13
- public class ComboBoxPopup : Popup
13
+ internal enum ComboBoxPopupPlacement
14
14
{
15
+ Undefined ,
16
+ Down ,
17
+ Up ,
18
+ Classic
19
+ }
20
+
21
+ internal class ComboBoxPopup : Popup
22
+ {
23
+ #region UpContentTemplate property
24
+
15
25
public static readonly DependencyProperty UpContentTemplateProperty
16
26
= DependencyProperty . Register ( nameof ( UpContentTemplate ) ,
17
27
typeof ( ControlTemplate ) ,
@@ -24,6 +34,10 @@ public ControlTemplate UpContentTemplate
24
34
set { SetValue ( UpContentTemplateProperty , value ) ; }
25
35
}
26
36
37
+ #endregion
38
+
39
+ #region DownContentTemplate region
40
+
27
41
public static readonly DependencyProperty DownContentTemplateProperty
28
42
= DependencyProperty . Register ( nameof ( DownContentTemplate ) ,
29
43
typeof ( ControlTemplate ) ,
@@ -36,18 +50,26 @@ public ControlTemplate DownContentTemplate
36
50
set { SetValue ( DownContentTemplateProperty , value ) ; }
37
51
}
38
52
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 ) ,
41
59
typeof ( ControlTemplate ) ,
42
60
typeof ( ComboBoxPopup ) ,
43
61
new UIPropertyMetadata ( null ) ) ;
44
62
45
- public ControlTemplate DefaultContentTemplate
63
+ public ControlTemplate ClassicContentTemplate
46
64
{
47
- get { return ( ControlTemplate ) GetValue ( DefaultContentTemplateProperty ) ; }
48
- set { SetValue ( DefaultContentTemplateProperty , value ) ; }
65
+ get { return ( ControlTemplate ) GetValue ( ClassicContentTemplateProperty ) ; }
66
+ set { SetValue ( ClassicContentTemplateProperty , value ) ; }
49
67
}
50
68
69
+ #endregion
70
+
71
+ #region UpVerticalOffset property
72
+
51
73
public static readonly DependencyProperty UpVerticalOffsetProperty
52
74
= DependencyProperty . Register ( nameof ( UpVerticalOffset ) ,
53
75
typeof ( double ) ,
@@ -60,6 +82,10 @@ public double UpVerticalOffset
60
82
set { SetValue ( UpVerticalOffsetProperty , value ) ; }
61
83
}
62
84
85
+ #endregion
86
+
87
+ #region DownVerticalOffset property
88
+
63
89
public static readonly DependencyProperty DownVerticalOffsetProperty
64
90
= DependencyProperty . Register ( nameof ( DownVerticalOffset ) ,
65
91
typeof ( double ) ,
@@ -72,6 +98,24 @@ public double DownVerticalOffset
72
98
set { SetValue ( DownVerticalOffsetProperty , value ) ; }
73
99
}
74
100
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
+
75
119
#region Background property
76
120
77
121
private static readonly DependencyPropertyKey BackgroundPropertyKey =
@@ -127,17 +171,6 @@ public ComboBoxPopup()
127
171
this . CustomPopupPlacementCallback = ComboBoxCustomPopupPlacementCallback ;
128
172
}
129
173
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
-
141
174
private void SetupBackground ( IEnumerable < DependencyObject > visualAncestry )
142
175
{
143
176
var background = visualAncestry
@@ -191,7 +224,7 @@ private CustomPopupPlacement[] ComboBoxCustomPopupPlacementCallback(
191
224
if ( locationX + popupSize . Width - realOffsetX > screenWidth
192
225
|| locationX - realOffsetX < 0 )
193
226
{
194
- SetChildTemplateIfNeed ( DefaultContentTemplate ) ;
227
+ PopupPlacement = ComboBoxPopupPlacement . Classic ;
195
228
196
229
var defaultVerticalOffsetIndepent = DpiHelper . TransformToDeviceY ( mainVisual , DefaultVerticalOffset ) ;
197
230
var newY = locationY + popupSize . Height > screenHeight
@@ -203,7 +236,7 @@ private CustomPopupPlacement[] ComboBoxCustomPopupPlacementCallback(
203
236
204
237
if ( locationY + popupSize . Height > screenHeight )
205
238
{
206
- SetChildTemplateIfNeed ( UpContentTemplate ) ;
239
+ PopupPlacement = ComboBoxPopupPlacement . Up ;
207
240
208
241
var upVerticalOffsetIndepent = DpiHelper . TransformToDeviceY ( mainVisual , UpVerticalOffset ) ;
209
242
var newY = upVerticalOffsetIndepent - popupSize . Height + targetSize . Height ;
@@ -212,13 +245,53 @@ private CustomPopupPlacement[] ComboBoxCustomPopupPlacementCallback(
212
245
}
213
246
else
214
247
{
215
- SetChildTemplateIfNeed ( DownContentTemplate ) ;
248
+ PopupPlacement = ComboBoxPopupPlacement . Down ;
216
249
217
250
var downVerticalOffsetIndepent = DpiHelper . TransformToDeviceY ( mainVisual , DownVerticalOffset ) ;
218
251
var newY = downVerticalOffsetIndepent ;
219
252
220
253
return new [ ] { new CustomPopupPlacement ( new Point ( offsetX , newY ) , PopupPrimaryAxis . None ) } ;
221
254
}
222
255
}
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
+ }
223
296
}
224
297
}
0 commit comments