Skip to content

Commit 414d4c3

Browse files
committed
Snackbar state management
1 parent 789185d commit 414d4c3

File tree

2 files changed

+58
-6
lines changed

2 files changed

+58
-6
lines changed

MaterialDesignThemes.Wpf/Snackbar.cs

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,35 @@ public object Message
5252

5353
public SnackbarActionEventHandler ActionHandler { get; internal set; }
5454

55+
private SnackbarState _state;
56+
57+
private SnackbarState State
58+
{
59+
get
60+
{
61+
return _state;
62+
}
63+
64+
set
65+
{
66+
_state = value;
67+
68+
// set the according visual state to trigger the animations
69+
if (_state == SnackbarState.Initialized)
70+
{
71+
VisualStateManager.GoToState(this, HiddenStateName, false);
72+
}
73+
else if (_state == SnackbarState.Visible)
74+
{
75+
VisualStateManager.GoToState(this, VisibleStateName, true);
76+
}
77+
else if (_state == SnackbarState.Hidden)
78+
{
79+
VisualStateManager.GoToState(this, HiddenStateName, true);
80+
}
81+
}
82+
}
83+
5584
private DispatcherTimer _timer;
5685

5786
static Snackbar()
@@ -66,15 +95,21 @@ public override void OnApplyTemplate()
6695
Button actionButton = (Button)GetTemplateChild(PartActionButtonName);
6796
actionButton.Click += ActionButtonClickHandler;
6897

69-
VisualStateManager.GoToState(this, HiddenStateName, false);
98+
State = SnackbarState.Initialized;
7099

71100
base.OnApplyTemplate();
72101
}
73102

74103
public async Task Show()
75104
{
76-
// trigger animation and wait for it
77-
VisualStateManager.GoToState(this, VisibleStateName, true);
105+
if (State != SnackbarState.Initialized)
106+
{
107+
// only a fresh initialized Snackbar can be shown
108+
return;
109+
}
110+
111+
// set the state, trigger the animation and wait for it
112+
State = SnackbarState.Visible;
78113

79114
await Task.Delay(300);
80115

@@ -90,11 +125,17 @@ public async Task Show()
90125

91126
public async Task Hide()
92127
{
128+
if (State != SnackbarState.Visible)
129+
{
130+
// only a visible Snackbar can be hidden
131+
return;
132+
}
133+
93134
// stop the timer
94135
_timer.Stop();
95136

96-
// trigger animation and wait for it
97-
VisualStateManager.GoToState(this, HiddenStateName, true);
137+
// set the state, trigger the animation and wait for it
138+
State = SnackbarState.Hidden;
98139

99140
await Task.Delay(300);
100141

@@ -126,5 +167,12 @@ private SnackbarHost FindSnackbarHost()
126167

127168
return null;
128169
}
170+
171+
private enum SnackbarState : byte
172+
{
173+
Initialized,
174+
Visible,
175+
Hidden
176+
}
129177
}
130178
}

MaterialDesignThemes.Wpf/SnackbarHost.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,11 @@ private async Task ShowInternalAsync(string message, string actionLabel, Snackba
115115
List<Snackbar> visibleSnackbars = _snackbarHostRoot.Children.OfType<Snackbar>().ToList();
116116

117117
// if there is one, first hide it (should be at most one)
118-
visibleSnackbars.ForEach(async visibleSnackbar => await visibleSnackbar.Hide());
118+
// use a foreach loop, because visibleSnackbars.ForEach(async visibleSnackbar => await visibleSnackbar.Hide()); will not work correctly on the UI
119+
foreach(Snackbar visibleSnackbar in visibleSnackbars)
120+
{
121+
await visibleSnackbar.Hide();
122+
}
119123

120124
// create a new Snackbar, place it inside the host and show it
121125
Snackbar snackbar = new Snackbar() { Message = message, ActionLabel = actionLabel, ActionHandler = actionHandler };

0 commit comments

Comments
 (0)