Skip to content

Commit a38e0be

Browse files
Streissidstreisselberger
andauthored
add opened/closing events to drawer host #2015 (#2139)
* add opened/closing events to drawer host * fix issues to comments from reviewer Co-authored-by: dstreisselberger <[email protected]>
1 parent b0e956f commit a38e0be

File tree

4 files changed

+215
-7
lines changed

4 files changed

+215
-7
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
using System;
2+
using System.ComponentModel;
3+
using System.Windows;
4+
using System.Windows.Controls;
5+
using Xunit;
6+
7+
namespace MaterialDesignThemes.Wpf.Tests
8+
{
9+
public class DrawerHostTests : IDisposable
10+
{
11+
private readonly DrawerHost _drawerHost;
12+
13+
public DrawerHostTests()
14+
{
15+
_drawerHost = new DrawerHost();
16+
_drawerHost.ApplyDefaultStyle();
17+
_drawerHost.RaiseEvent(new RoutedEventArgs(FrameworkElement.LoadedEvent));
18+
}
19+
20+
public void Dispose()
21+
{
22+
_drawerHost.RaiseEvent(new RoutedEventArgs(FrameworkElement.UnloadedEvent));
23+
}
24+
25+
[StaFact]
26+
[Description("Issue 2015")]
27+
public void WhenOpenedDrawerOpenedEventIsRaised()
28+
{
29+
Dock expectedPosition = Dock.Left;
30+
Dock openedPosition = Dock.Top;
31+
_drawerHost.DrawerOpened += DrawerOpened;
32+
_drawerHost.IsLeftDrawerOpen = true;
33+
34+
DrawerHost.CloseDrawerCommand.Execute(Dock.Left, _drawerHost);
35+
36+
Assert.Equal(expectedPosition, openedPosition);
37+
38+
void DrawerOpened(object sender, DrawerOpenedEventArgs eventArgs)
39+
{
40+
openedPosition = eventArgs.Dock;
41+
}
42+
}
43+
44+
[StaFact]
45+
[Description("Issue 2015")]
46+
public void WhenClosingDrawerClosingEventIsRaised()
47+
{
48+
Dock expectedPosition = Dock.Left;
49+
Dock closedPosition = Dock.Top;
50+
_drawerHost.DrawerClosing += DrawerClosing;
51+
_drawerHost.IsLeftDrawerOpen = true;
52+
53+
DrawerHost.CloseDrawerCommand.Execute(Dock.Left, _drawerHost);
54+
55+
Assert.Equal(expectedPosition, closedPosition);
56+
57+
void DrawerClosing(object sender, DrawerClosingEventArgs eventArgs)
58+
{
59+
closedPosition = eventArgs.Dock;
60+
}
61+
}
62+
}
63+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System.Windows;
2+
using System.Windows.Controls;
3+
4+
namespace MaterialDesignThemes.Wpf
5+
{
6+
public class DrawerClosingEventArgs : RoutedEventArgs
7+
{
8+
public DrawerClosingEventArgs(Dock dock, RoutedEvent routedEvent) : base(routedEvent)
9+
{
10+
Dock = dock;
11+
}
12+
13+
/// <summary>
14+
/// Cancel the close.
15+
/// </summary>
16+
public void Cancel()
17+
{
18+
IsCancelled = true;
19+
}
20+
21+
/// <summary>
22+
/// Indicates if the close has already been cancelled.
23+
/// </summary>
24+
public bool IsCancelled { get; private set; }
25+
26+
/// <summary>
27+
/// Allows interation with the current dialog session.
28+
/// </summary>
29+
public Dock Dock { get; }
30+
}
31+
}

MaterialDesignThemes.Wpf/DrawerHost.cs

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

109
namespace MaterialDesignThemes.Wpf
1110
{
@@ -135,7 +134,7 @@ public Brush TopDrawerBackground
135134
}
136135

137136
public static readonly DependencyProperty IsTopDrawerOpenProperty = DependencyProperty.Register(
138-
nameof(IsTopDrawerOpen), typeof(bool), typeof(DrawerHost), new FrameworkPropertyMetadata(default(bool), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, IsDrawerOpenPropertyChangedCallback));
137+
nameof(IsTopDrawerOpen), typeof(bool), typeof(DrawerHost), new FrameworkPropertyMetadata(default(bool), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, IsTopDrawerOpenPropertyChangedCallback));
139138

140139
public bool IsTopDrawerOpen
141140
{
@@ -164,6 +163,7 @@ public bool TopDrawerCloseOnClickAway
164163
get { return (bool)GetValue(TopDrawerCloseOnClickAwayProperty); }
165164
set { SetValue(TopDrawerCloseOnClickAwayProperty, value); }
166165
}
166+
167167
#endregion
168168

169169
#region left drawer
@@ -214,7 +214,7 @@ public Brush LeftDrawerBackground
214214
}
215215

216216
public static readonly DependencyProperty IsLeftDrawerOpenProperty = DependencyProperty.Register(
217-
nameof(IsLeftDrawerOpen), typeof(bool), typeof(DrawerHost), new FrameworkPropertyMetadata(default(bool), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, IsDrawerOpenPropertyChangedCallback));
217+
nameof(IsLeftDrawerOpen), typeof(bool), typeof(DrawerHost), new FrameworkPropertyMetadata(default(bool), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, IsLeftDrawerOpenPropertyChangedCallback));
218218

219219
public bool IsLeftDrawerOpen
220220
{
@@ -294,7 +294,7 @@ public Brush RightDrawerBackground
294294
}
295295

296296
public static readonly DependencyProperty IsRightDrawerOpenProperty = DependencyProperty.Register(
297-
nameof(IsRightDrawerOpen), typeof(bool), typeof(DrawerHost), new FrameworkPropertyMetadata(default(bool), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, IsDrawerOpenPropertyChangedCallback));
297+
nameof(IsRightDrawerOpen), typeof(bool), typeof(DrawerHost), new FrameworkPropertyMetadata(default(bool), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, IsRightDrawerOpenPropertyChangedCallback));
298298

299299
public bool IsRightDrawerOpen
300300
{
@@ -374,7 +374,7 @@ public Brush BottomDrawerBackground
374374
}
375375

376376
public static readonly DependencyProperty IsBottomDrawerOpenProperty = DependencyProperty.Register(
377-
nameof(IsBottomDrawerOpen), typeof(bool), typeof(DrawerHost), new FrameworkPropertyMetadata(default(bool), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, IsDrawerOpenPropertyChangedCallback));
377+
nameof(IsBottomDrawerOpen), typeof(bool), typeof(DrawerHost), new FrameworkPropertyMetadata(default(bool), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, IsBottomDrawerOpenPropertyChangedCallback));
378378

379379
public bool IsBottomDrawerOpen
380380
{
@@ -406,6 +406,56 @@ public bool BottomDrawerCloseOnClickAway
406406

407407
#endregion
408408

409+
#region open drawer events/callbacks
410+
411+
public static readonly RoutedEvent DrawerOpenedEvent =
412+
EventManager.RegisterRoutedEvent(
413+
"DrawerOpened",
414+
RoutingStrategy.Bubble,
415+
typeof(EventHandler<DrawerOpenedEventArgs>),
416+
typeof(DrawerHost));
417+
418+
/// <summary>
419+
/// Raised when a drawer is opened.
420+
/// </summary>
421+
public event EventHandler<DrawerOpenedEventArgs> DrawerOpened
422+
{
423+
add { AddHandler(DrawerOpenedEvent, value); }
424+
remove { RemoveHandler(DrawerOpenedEvent, value); }
425+
}
426+
427+
protected void OnDrawerOpened(DrawerOpenedEventArgs eventArgs)
428+
{
429+
RaiseEvent(eventArgs);
430+
}
431+
432+
#endregion
433+
434+
#region close drawer events/callbacks
435+
436+
public static readonly RoutedEvent DrawerClosingEvent =
437+
EventManager.RegisterRoutedEvent(
438+
"DrawerClosing",
439+
RoutingStrategy.Bubble,
440+
typeof(EventHandler<DrawerClosingEventArgs>),
441+
typeof(DrawerHost));
442+
443+
/// <summary>
444+
/// Raised when a drawer is closing.
445+
/// </summary>
446+
public event EventHandler<DrawerClosingEventArgs> DrawerClosing
447+
{
448+
add { AddHandler(DrawerClosingEvent, value); }
449+
remove { RemoveHandler(DrawerClosingEvent, value); }
450+
}
451+
452+
protected void OnDrawerClosing(DrawerClosingEventArgs eventArgs)
453+
{
454+
RaiseEvent(eventArgs);
455+
}
456+
457+
#endregion
458+
409459
public override void OnApplyTemplate()
410460
{
411461
if (_templateContentCoverElement != null)
@@ -500,12 +550,45 @@ private void UpdateVisualStates(bool? useTransitions = null)
500550
IsBottomDrawerOpen ? TemplateBottomOpenStateName : TemplateBottomClosedStateName, useTransitions.HasValue ? useTransitions.Value : !TransitionAssist.GetDisableTransitions(this));
501551
}
502552

503-
private static void IsDrawerOpenPropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
553+
private static void IsTopDrawerOpenPropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
554+
{
555+
IsDrawerOpenPropertyChanged(dependencyObject, dependencyPropertyChangedEventArgs, Dock.Top);
556+
}
557+
558+
private static void IsLeftDrawerOpenPropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
559+
{
560+
IsDrawerOpenPropertyChanged(dependencyObject, dependencyPropertyChangedEventArgs, Dock.Left);
561+
}
562+
563+
private static void IsRightDrawerOpenPropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
564+
{
565+
IsDrawerOpenPropertyChanged(dependencyObject, dependencyPropertyChangedEventArgs, Dock.Right);
566+
}
567+
568+
private static void IsBottomDrawerOpenPropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
569+
{
570+
IsDrawerOpenPropertyChanged(dependencyObject, dependencyPropertyChangedEventArgs, Dock.Bottom);
571+
}
572+
573+
private static void IsDrawerOpenPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs, Dock dock)
504574
{
505575
var drawerHost = (DrawerHost)dependencyObject;
506576
if (!drawerHost._lockZIndexes && (bool)dependencyPropertyChangedEventArgs.NewValue)
507577
drawerHost.PrepareZIndexes(drawerHost._zIndexPropertyLookup[dependencyPropertyChangedEventArgs.Property]);
508578
drawerHost.UpdateVisualStates();
579+
580+
if ((bool)dependencyPropertyChangedEventArgs.NewValue)
581+
{
582+
RaiseDrawerOpened(drawerHost, dock);
583+
}
584+
}
585+
586+
private static void RaiseDrawerOpened(DrawerHost drawerHost, Dock dock)
587+
{
588+
//multiple ways of calling back that the drawer has opened:
589+
// * routed event
590+
var drawerOpenedEventArgs = new DrawerOpenedEventArgs(dock, DrawerOpenedEvent);
591+
drawerHost.OnDrawerOpened(drawerOpenedEventArgs);
509592
}
510593

511594
private void PrepareZIndexes(DependencyPropertyKey zIndexDependencyPropertyKey)
@@ -524,6 +607,19 @@ private void CloseDrawerHandler(object sender, ExecutedRoutedEventArgs executedR
524607
{
525608
if (executedRoutedEventArgs.Handled) return;
526609

610+
if (executedRoutedEventArgs.Parameter is Dock dock)
611+
{
612+
var drawerClosingEventArgs = new DrawerClosingEventArgs(dock, DrawerClosingEvent);
613+
//multiple ways of calling back that the drawer is closing:
614+
// * routed event
615+
OnDrawerClosing(drawerClosingEventArgs);
616+
617+
if (drawerClosingEventArgs.IsCancelled)
618+
{
619+
return;
620+
}
621+
}
622+
527623
SetOpenFlag(executedRoutedEventArgs, false);
528624

529625
executedRoutedEventArgs.Handled = true;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System.Windows;
2+
using System.Windows.Controls;
3+
4+
namespace MaterialDesignThemes.Wpf
5+
{
6+
public class DrawerOpenedEventArgs : RoutedEventArgs
7+
{
8+
public DrawerOpenedEventArgs(Dock dock, RoutedEvent routedEvent) : base(routedEvent)
9+
{
10+
Dock = dock;
11+
}
12+
13+
/// <summary>
14+
/// Allows interation with the current dialog session.
15+
/// </summary>
16+
public Dock Dock { get; }
17+
}
18+
}

0 commit comments

Comments
 (0)