Skip to content

Commit a9e4738

Browse files
committed
manage zindexes
1 parent 1038895 commit a9e4738

File tree

3 files changed

+220
-46
lines changed

3 files changed

+220
-46
lines changed

MainDemo.Wpf/ProvingGround.xaml

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
<UserControl.Resources>
1313
<ResourceDictionary>
1414
<ResourceDictionary.MergedDictionaries>
15+
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Button.xaml" />
1516
<!--
1617
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
1718
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.ProgressBar.xaml" />
@@ -29,7 +30,6 @@
2930
</UserControl.Resources>
3031

3132
<materialDesign:DrawerHost>
32-
<!--
3333
<materialDesign:DrawerHost.LeftDrawerContent>
3434
<StackPanel Margin="16">
3535
<TextBlock>LEFT STUFF</TextBlock>
@@ -38,16 +38,15 @@
3838
</Button>
3939
</StackPanel>
4040
</materialDesign:DrawerHost.LeftDrawerContent>
41-
-->
4241
<materialDesign:DrawerHost.TopDrawerContent>
4342
<StackPanel Margin="16" HorizontalAlignment="Center">
4443
<TextBlock>TOP STUFF</TextBlock>
45-
<Button Command="{x:Static materialDesign:DrawerHost.CloseDrawerCommand}">
44+
<Button Command="{x:Static materialDesign:DrawerHost.CloseDrawerCommand}"
45+
Style="{DynamicResource MaterialDesignFlatButton}">
4646
Close
4747
</Button>
4848
</StackPanel>
4949
</materialDesign:DrawerHost.TopDrawerContent>
50-
<!--
5150
<materialDesign:DrawerHost.RightDrawerContent>
5251
<StackPanel Margin="16">
5352
<TextBlock> Hello World</TextBlock>
@@ -56,7 +55,15 @@
5655
</Button>
5756
</StackPanel>
5857
</materialDesign:DrawerHost.RightDrawerContent>
59-
-->
58+
<materialDesign:DrawerHost.BottomDrawerContent>
59+
<StackPanel Margin="16" HorizontalAlignment="Center">
60+
<TextBlock>BOTTOM STUFF</TextBlock>
61+
<Button Command="{x:Static materialDesign:DrawerHost.CloseDrawerCommand}"
62+
Style="{DynamicResource MaterialDesignFlatButton}">
63+
Close
64+
</Button>
65+
</StackPanel>
66+
</materialDesign:DrawerHost.BottomDrawerContent>
6067
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
6168
<Button Command="{x:Static materialDesign:DrawerHost.OpenDrawerCommand}">
6269
Open sesame

MaterialDesignThemes.Wpf/DrawerHost.cs

Lines changed: 168 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
using System;
2+
using System.Linq;
23
using System.Windows;
34
using System.Windows.Controls;
45
using System.Windows.Input;
56
using System.Windows.Media;
67
using MaterialDesignThemes.Wpf.Transitions;
8+
using System.Collections.Generic;
79

810
namespace MaterialDesignThemes.Wpf
911
{
@@ -18,6 +20,10 @@ namespace MaterialDesignThemes.Wpf
1820
[TemplateVisualState(GroupName = TemplateBottomDrawerGroupName, Name = TemplateBottomClosedStateName)]
1921
[TemplateVisualState(GroupName = TemplateBottomDrawerGroupName, Name = TemplateBottomOpenStateName)]
2022
[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))]
2127
public class DrawerHost : ContentControl
2228
{
2329
public const string TemplateAllDrawersGroupName = "AllDrawers";
@@ -37,11 +43,29 @@ public class DrawerHost : ContentControl
3743
public const string TemplateBottomOpenStateName = "BottomDrawerOpen";
3844

3945
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";
4050

4151
public static RoutedCommand OpenDrawerCommand = new RoutedCommand();
4252
public static RoutedCommand CloseDrawerCommand = new RoutedCommand();
4353

4454
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+
};
4569

4670
static DrawerHost()
4771
{
@@ -54,6 +78,8 @@ public DrawerHost()
5478
CommandBindings.Add(new CommandBinding(CloseDrawerCommand, CloseDrawerHandler));
5579
}
5680

81+
#region top drawer
82+
5783
public static readonly DependencyProperty TopDrawerContentProperty = DependencyProperty.Register(
5884
nameof(TopDrawerContent), typeof(object), typeof(DrawerHost), new PropertyMetadata(default(object)));
5985

@@ -108,6 +134,23 @@ public bool IsTopDrawerOpen
108134
set { SetValue(IsTopDrawerOpenProperty, value); }
109135
}
110136

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+
111154
public static readonly DependencyProperty LeftDrawerContentProperty = DependencyProperty.Register(
112155
nameof(LeftDrawerContent), typeof (object), typeof (DrawerHost), new PropertyMetadata(default(object)));
113156

@@ -162,6 +205,23 @@ public bool IsLeftDrawerOpen
162205
set { SetValue(IsLeftDrawerOpenProperty, value); }
163206
}
164207

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+
165225
public static readonly DependencyProperty RightDrawerContentProperty = DependencyProperty.Register(
166226
nameof(RightDrawerContent), typeof(object), typeof(DrawerHost), new PropertyMetadata(default(object)));
167227

@@ -216,6 +276,23 @@ public bool IsRightDrawerOpen
216276
set { SetValue(IsRightDrawerOpenProperty, value); }
217277
}
218278

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+
219296
public static readonly DependencyProperty BottomDrawerContentProperty = DependencyProperty.Register(
220297
nameof(BottomDrawerContent), typeof(object), typeof(DrawerHost), new PropertyMetadata(default(object)));
221298

@@ -270,20 +347,83 @@ public bool IsBottomDrawerOpen
270347
set { SetValue(IsBottomDrawerOpenProperty, value); }
271348
}
272349

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+
273365
public override void OnApplyTemplate()
274366
{
275367
if (_templateContentCoverElement != null)
276368
_templateContentCoverElement.PreviewMouseLeftButtonUp += TemplateContentCoverElementOnPreviewMouseLeftButtonUp;
369+
WireDrawer(_leftDrawerElement, true);
370+
WireDrawer(_topDrawerElement, true);
371+
WireDrawer(_rightDrawerElement, true);
372+
WireDrawer(_bottomDrawerElement, true);
277373

278374
base.OnApplyTemplate();
279375

280376
_templateContentCoverElement = GetTemplateChild(TemplateContentCoverPartName) as FrameworkElement;
281377
if (_templateContentCoverElement != null)
282378
_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);
283383

284384
UpdateVisualStates(false);
285385
}
286386

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+
287427
private void TemplateContentCoverElementOnPreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs mouseButtonEventArgs)
288428
{
289429
SetCurrentValue(IsLeftDrawerOpenProperty, false);
@@ -314,7 +454,22 @@ private void UpdateVisualStates(bool? useTransitions = null)
314454

315455
private static void IsDrawerOpenPropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
316456
{
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);
318473
}
319474

320475
private void CloseDrawerHandler(object sender, ExecutedRoutedEventArgs executedRoutedEventArgs)
@@ -359,10 +514,18 @@ private void SetOpenFlag(ExecutedRoutedEventArgs executedRoutedEventArgs, bool v
359514
}
360515
else
361516
{
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+
}
366529
}
367530
}
368531
}

0 commit comments

Comments
 (0)