1
1
using System ;
2
+ using System . Linq ;
2
3
using System . Windows ;
3
4
using System . Windows . Controls ;
4
5
using System . Windows . Input ;
5
6
using System . Windows . Media ;
6
7
using MaterialDesignThemes . Wpf . Transitions ;
8
+ using System . Collections . Generic ;
7
9
8
10
namespace MaterialDesignThemes . Wpf
9
11
{
@@ -18,6 +20,10 @@ namespace MaterialDesignThemes.Wpf
18
20
[ TemplateVisualState ( GroupName = TemplateBottomDrawerGroupName , Name = TemplateBottomClosedStateName ) ]
19
21
[ TemplateVisualState ( GroupName = TemplateBottomDrawerGroupName , Name = TemplateBottomOpenStateName ) ]
20
22
[ TemplatePart ( Name = TemplateContentCoverPartName , Type = typeof ( FrameworkElement ) ) ]
23
+ [ TemplatePart ( Name = TemplateLeftDrawerPartName , Type = typeof ( FrameworkElement ) ) ]
24
+ [ TemplatePart ( Name = TemplateTopDrawerPartName , Type = typeof ( FrameworkElement ) ) ]
25
+ [ TemplatePart ( Name = TemplateRightDrawerPartName , Type = typeof ( FrameworkElement ) ) ]
26
+ [ TemplatePart ( Name = TemplateBottomDrawerPartName , Type = typeof ( FrameworkElement ) ) ]
21
27
public class DrawerHost : ContentControl
22
28
{
23
29
public const string TemplateAllDrawersGroupName = "AllDrawers" ;
@@ -37,11 +43,29 @@ public class DrawerHost : ContentControl
37
43
public const string TemplateBottomOpenStateName = "BottomDrawerOpen" ;
38
44
39
45
public const string TemplateContentCoverPartName = "PART_ContentCover" ;
46
+ public const string TemplateLeftDrawerPartName = "PART_LeftDrawer" ;
47
+ public const string TemplateTopDrawerPartName = "PART_TopDrawer" ;
48
+ public const string TemplateRightDrawerPartName = "PART_RightDrawer" ;
49
+ public const string TemplateBottomDrawerPartName = "PART_BottomDrawer" ;
40
50
41
51
public static RoutedCommand OpenDrawerCommand = new RoutedCommand ( ) ;
42
52
public static RoutedCommand CloseDrawerCommand = new RoutedCommand ( ) ;
43
53
44
54
private FrameworkElement _templateContentCoverElement ;
55
+ private FrameworkElement _leftDrawerElement ;
56
+ private FrameworkElement _topDrawerElement ;
57
+ private FrameworkElement _rightDrawerElement ;
58
+ private FrameworkElement _bottomDrawerElement ;
59
+
60
+ private bool _lockZIndexes ;
61
+
62
+ private readonly IDictionary < DependencyProperty , DependencyPropertyKey > _zIndexPropertyLookup = new Dictionary < DependencyProperty , DependencyPropertyKey >
63
+ {
64
+ { IsLeftDrawerOpenProperty , LeftDrawerZIndexPropertyKey } ,
65
+ { IsTopDrawerOpenProperty , TopDrawerZIndexPropertyKey } ,
66
+ { IsRightDrawerOpenProperty , RightDrawerZIndexPropertyKey } ,
67
+ { IsBottomDrawerOpenProperty , BottomDrawerZIndexPropertyKey }
68
+ } ;
45
69
46
70
static DrawerHost ( )
47
71
{
@@ -54,6 +78,8 @@ public DrawerHost()
54
78
CommandBindings . Add ( new CommandBinding ( CloseDrawerCommand , CloseDrawerHandler ) ) ;
55
79
}
56
80
81
+ #region top drawer
82
+
57
83
public static readonly DependencyProperty TopDrawerContentProperty = DependencyProperty . Register (
58
84
nameof ( TopDrawerContent ) , typeof ( object ) , typeof ( DrawerHost ) , new PropertyMetadata ( default ( object ) ) ) ;
59
85
@@ -108,6 +134,23 @@ public bool IsTopDrawerOpen
108
134
set { SetValue ( IsTopDrawerOpenProperty , value ) ; }
109
135
}
110
136
137
+ private static readonly DependencyPropertyKey TopDrawerZIndexPropertyKey =
138
+ DependencyProperty . RegisterReadOnly (
139
+ "TopDrawerZIndex" , typeof ( int ) , typeof ( DrawerHost ) ,
140
+ new PropertyMetadata ( 4 ) ) ;
141
+
142
+ public static readonly DependencyProperty TopDrawerZIndexProperty = TopDrawerZIndexPropertyKey . DependencyProperty ;
143
+
144
+ public int TopDrawerZIndex
145
+ {
146
+ get { return ( int ) GetValue ( TopDrawerZIndexProperty ) ; }
147
+ private set { SetValue ( TopDrawerZIndexPropertyKey , value ) ; }
148
+ }
149
+
150
+ #endregion
151
+
152
+ #region left drawer
153
+
111
154
public static readonly DependencyProperty LeftDrawerContentProperty = DependencyProperty . Register (
112
155
nameof ( LeftDrawerContent ) , typeof ( object ) , typeof ( DrawerHost ) , new PropertyMetadata ( default ( object ) ) ) ;
113
156
@@ -162,6 +205,23 @@ public bool IsLeftDrawerOpen
162
205
set { SetValue ( IsLeftDrawerOpenProperty , value ) ; }
163
206
}
164
207
208
+ private static readonly DependencyPropertyKey LeftDrawerZIndexPropertyKey =
209
+ DependencyProperty . RegisterReadOnly (
210
+ "LeftDrawerZIndex" , typeof ( int ) , typeof ( DrawerHost ) ,
211
+ new PropertyMetadata ( 2 ) ) ;
212
+
213
+ public static readonly DependencyProperty LeftDrawerZIndexProperty = LeftDrawerZIndexPropertyKey . DependencyProperty ;
214
+
215
+ public int LeftDrawerZIndex
216
+ {
217
+ get { return ( int ) GetValue ( LeftDrawerZIndexProperty ) ; }
218
+ private set { SetValue ( LeftDrawerZIndexPropertyKey , value ) ; }
219
+ }
220
+
221
+ #endregion
222
+
223
+ #region right drawer
224
+
165
225
public static readonly DependencyProperty RightDrawerContentProperty = DependencyProperty . Register (
166
226
nameof ( RightDrawerContent ) , typeof ( object ) , typeof ( DrawerHost ) , new PropertyMetadata ( default ( object ) ) ) ;
167
227
@@ -216,6 +276,23 @@ public bool IsRightDrawerOpen
216
276
set { SetValue ( IsRightDrawerOpenProperty , value ) ; }
217
277
}
218
278
279
+ private static readonly DependencyPropertyKey RightDrawerZIndexPropertyKey =
280
+ DependencyProperty . RegisterReadOnly (
281
+ "RightDrawerZIndex" , typeof ( int ) , typeof ( DrawerHost ) ,
282
+ new PropertyMetadata ( 1 ) ) ;
283
+
284
+ public static readonly DependencyProperty RightDrawerZIndexProperty = RightDrawerZIndexPropertyKey . DependencyProperty ;
285
+
286
+ public int RightDrawerZIndex
287
+ {
288
+ get { return ( int ) GetValue ( RightDrawerZIndexProperty ) ; }
289
+ private set { SetValue ( RightDrawerZIndexPropertyKey , value ) ; }
290
+ }
291
+
292
+ #endregion
293
+
294
+ #region bottom drawer
295
+
219
296
public static readonly DependencyProperty BottomDrawerContentProperty = DependencyProperty . Register (
220
297
nameof ( BottomDrawerContent ) , typeof ( object ) , typeof ( DrawerHost ) , new PropertyMetadata ( default ( object ) ) ) ;
221
298
@@ -270,20 +347,83 @@ public bool IsBottomDrawerOpen
270
347
set { SetValue ( IsBottomDrawerOpenProperty , value ) ; }
271
348
}
272
349
350
+ private static readonly DependencyPropertyKey BottomDrawerZIndexPropertyKey =
351
+ DependencyProperty . RegisterReadOnly (
352
+ "BottomDrawerZIndex" , typeof ( int ) , typeof ( DrawerHost ) ,
353
+ new PropertyMetadata ( 3 ) ) ;
354
+
355
+ public static readonly DependencyProperty BottomDrawerZIndexProperty = BottomDrawerZIndexPropertyKey . DependencyProperty ;
356
+
357
+ public int BottomDrawerZIndex
358
+ {
359
+ get { return ( int ) GetValue ( BottomDrawerZIndexProperty ) ; }
360
+ private set { SetValue ( BottomDrawerZIndexPropertyKey , value ) ; }
361
+ }
362
+
363
+ #endregion
364
+
273
365
public override void OnApplyTemplate ( )
274
366
{
275
367
if ( _templateContentCoverElement != null )
276
368
_templateContentCoverElement . PreviewMouseLeftButtonUp += TemplateContentCoverElementOnPreviewMouseLeftButtonUp ;
369
+ WireDrawer ( _leftDrawerElement , true ) ;
370
+ WireDrawer ( _topDrawerElement , true ) ;
371
+ WireDrawer ( _rightDrawerElement , true ) ;
372
+ WireDrawer ( _bottomDrawerElement , true ) ;
277
373
278
374
base . OnApplyTemplate ( ) ;
279
375
280
376
_templateContentCoverElement = GetTemplateChild ( TemplateContentCoverPartName ) as FrameworkElement ;
281
377
if ( _templateContentCoverElement != null )
282
378
_templateContentCoverElement . PreviewMouseLeftButtonUp += TemplateContentCoverElementOnPreviewMouseLeftButtonUp ;
379
+ _leftDrawerElement = WireDrawer ( GetTemplateChild ( TemplateLeftDrawerPartName ) as FrameworkElement , false ) ;
380
+ _topDrawerElement = WireDrawer ( GetTemplateChild ( TemplateTopDrawerPartName ) as FrameworkElement , false ) ;
381
+ _rightDrawerElement = WireDrawer ( GetTemplateChild ( TemplateRightDrawerPartName ) as FrameworkElement , false ) ;
382
+ _bottomDrawerElement = WireDrawer ( GetTemplateChild ( TemplateBottomDrawerPartName ) as FrameworkElement , false ) ;
283
383
284
384
UpdateVisualStates ( false ) ;
285
385
}
286
386
387
+ private FrameworkElement WireDrawer ( FrameworkElement drawerElement , bool unwire )
388
+ {
389
+ if ( drawerElement == null ) return null ;
390
+
391
+ if ( unwire )
392
+ {
393
+ drawerElement . GotFocus -= DrawerElement_GotFocus ;
394
+ drawerElement . MouseDown -= DrawerElement_MouseDown ;
395
+
396
+ return drawerElement ;
397
+ }
398
+
399
+ drawerElement . GotFocus += DrawerElement_GotFocus ;
400
+ drawerElement . MouseDown += DrawerElement_MouseDown ;
401
+
402
+ return drawerElement ;
403
+ }
404
+
405
+ private void DrawerElement_MouseDown ( object sender , MouseButtonEventArgs e )
406
+ {
407
+ ReactToFocus ( sender ) ;
408
+ }
409
+
410
+ private void DrawerElement_GotFocus ( object sender , RoutedEventArgs e )
411
+ {
412
+ ReactToFocus ( sender ) ;
413
+ }
414
+
415
+ private void ReactToFocus ( object sender )
416
+ {
417
+ if ( sender == _leftDrawerElement )
418
+ PrepareZIndexes ( LeftDrawerZIndexPropertyKey ) ;
419
+ else if ( sender == _topDrawerElement )
420
+ PrepareZIndexes ( TopDrawerZIndexPropertyKey ) ;
421
+ else if ( sender == _rightDrawerElement )
422
+ PrepareZIndexes ( RightDrawerZIndexPropertyKey ) ;
423
+ else if ( sender == _bottomDrawerElement )
424
+ PrepareZIndexes ( BottomDrawerZIndexPropertyKey ) ;
425
+ }
426
+
287
427
private void TemplateContentCoverElementOnPreviewMouseLeftButtonUp ( object sender , MouseButtonEventArgs mouseButtonEventArgs )
288
428
{
289
429
SetCurrentValue ( IsLeftDrawerOpenProperty , false ) ;
@@ -314,7 +454,22 @@ private void UpdateVisualStates(bool? useTransitions = null)
314
454
315
455
private static void IsDrawerOpenPropertyChangedCallback ( DependencyObject dependencyObject , DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs )
316
456
{
317
- ( ( DrawerHost ) dependencyObject ) . UpdateVisualStates ( ) ;
457
+ var drawerHost = ( DrawerHost ) dependencyObject ;
458
+ if ( ! drawerHost . _lockZIndexes && ( bool ) dependencyPropertyChangedEventArgs . NewValue )
459
+ drawerHost . PrepareZIndexes ( drawerHost . _zIndexPropertyLookup [ dependencyPropertyChangedEventArgs . Property ] ) ;
460
+ drawerHost . UpdateVisualStates ( ) ;
461
+ }
462
+
463
+ private void PrepareZIndexes ( DependencyPropertyKey zIndexDependencyPropertyKey )
464
+ {
465
+ var newOrder = new [ ] { zIndexDependencyPropertyKey }
466
+ . Concat ( _zIndexPropertyLookup . Values . Except ( new [ ] { zIndexDependencyPropertyKey } )
467
+ . OrderByDescending ( dpk => ( int ) GetValue ( dpk . DependencyProperty ) ) )
468
+ . Reverse ( )
469
+ . Select ( ( dpk , idx ) => new { dpk , idx } ) ;
470
+
471
+ foreach ( var a in newOrder )
472
+ SetValue ( a . dpk , a . idx ) ;
318
473
}
319
474
320
475
private void CloseDrawerHandler ( object sender , ExecutedRoutedEventArgs executedRoutedEventArgs )
@@ -359,10 +514,18 @@ private void SetOpenFlag(ExecutedRoutedEventArgs executedRoutedEventArgs, bool v
359
514
}
360
515
else
361
516
{
362
- SetCurrentValue ( IsLeftDrawerOpenProperty , value ) ;
363
- SetCurrentValue ( IsTopDrawerOpenProperty , value ) ;
364
- SetCurrentValue ( IsRightDrawerOpenProperty , value ) ;
365
- SetCurrentValue ( IsBottomDrawerOpenProperty , value ) ;
517
+ try
518
+ {
519
+ _lockZIndexes = true ;
520
+ SetCurrentValue ( IsLeftDrawerOpenProperty , value ) ;
521
+ SetCurrentValue ( IsTopDrawerOpenProperty , value ) ;
522
+ SetCurrentValue ( IsRightDrawerOpenProperty , value ) ;
523
+ SetCurrentValue ( IsBottomDrawerOpenProperty , value ) ;
524
+ }
525
+ finally
526
+ {
527
+ _lockZIndexes = false ;
528
+ }
366
529
}
367
530
}
368
531
}
0 commit comments