Skip to content

Commit 06e7c52

Browse files
committed
pump working with pause and mouse over mechanics
1 parent 1ec5a66 commit 06e7c52

File tree

7 files changed

+415
-161
lines changed

7 files changed

+415
-161
lines changed

MainDemo.Wpf/ProvingGround.xaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
<ColumnDefinition />
4242
<ColumnDefinition />
4343
<ColumnDefinition />
44+
<ColumnDefinition />
4445
</Grid.ColumnDefinitions>
4546

4647
<!-- example 1 -->
@@ -85,6 +86,18 @@
8586
<Button Click="SnackBar3_OnClick" HorizontalAlignment="Center">Send</Button>
8687
</StackPanel>
8788

89+
<!-- example 4 -->
90+
<!-- uses some action command call backs -->
91+
<materialDesign:Snackbar2 MessageQueue="{materialDesign:MessageQueue}"
92+
Grid.Row="0"
93+
Grid.Column="3"
94+
x:Name="SnackbarFour" />
95+
96+
<Button Click="SnackBar4_OnClick" HorizontalAlignment="Center"
97+
Grid.Row="1" Grid.Column="3"
98+
>Send</Button>
99+
100+
88101
</Grid>
89102

90103
</UserControl>

MainDemo.Wpf/ProvingGround.xaml.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Collections.ObjectModel;
44
using System.ComponentModel;
5+
using System.Diagnostics;
56
using System.Linq;
67
using System.Runtime.CompilerServices;
78
using System.Text;
@@ -43,6 +44,16 @@ private void SnackBar3_OnClick(object sender, RoutedEventArgs e)
4344
//the message queue can be called from any thread
4445
Task.Factory.StartNew(() => messageQueue.Enqueue(message));
4546
}
47+
48+
private void SnackBar4_OnClick(object sender, RoutedEventArgs e)
49+
{
50+
var id = "A1A";
51+
SnackbarFour.MessageQueue.Enqueue(
52+
$"Deleted {id}",
53+
"UNDO",
54+
param => Trace.WriteLine("Undo delete of " + param),
55+
id);
56+
}
4657
}
4758

4859
public class ProvingGroundViewModel : INotifyPropertyChanged

MaterialDesignThemes.Wpf/MaterialDesignThemes.Wpf.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@
298298
<Compile Include="MessageQueueExtension.cs" />
299299
<Compile Include="Palette.cs" />
300300
<Compile Include="Snackbar.cs" />
301+
<Compile Include="SnackbarMessage.cs" />
301302
<Compile Include="SnackbarMessageEventArgs.cs" />
302303
<Compile Include="SnackbarMessageQueue.cs" />
303304
<Compile Include="SnackbarMessageQueueItem.cs" />

MaterialDesignThemes.Wpf/Snackbar.cs

Lines changed: 25 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.Collections.Concurrent;
3-
using System.ComponentModel;
43
using System.Runtime.InteropServices;
54
using System.Text;
65
using System.Threading.Tasks;
@@ -12,7 +11,6 @@
1211
using System.Windows.Media;
1312
using System.Windows.Media.Animation;
1413
using System.Windows.Threading;
15-
using MaterialDesignThemes.Wpf.Converters;
1614

1715
namespace MaterialDesignThemes.Wpf
1816
{
@@ -62,6 +60,29 @@ public bool IsActive
6260
{
6361
get { return (bool) GetValue(IsActiveProperty); }
6462
set { SetValue(IsActiveProperty, value); }
63+
}
64+
65+
public event RoutedPropertyChangedEventHandler<bool> IsActiveChanged
66+
{
67+
add { AddHandler(IsActiveChangedEvent, value); }
68+
remove { RemoveHandler(IsActiveChangedEvent, value); }
69+
}
70+
71+
public static readonly RoutedEvent IsActiveChangedEvent =
72+
EventManager.RegisterRoutedEvent(
73+
"IsActiveChanged",
74+
RoutingStrategy.Bubble,
75+
typeof(RoutedPropertyChangedEventHandler<bool>),
76+
typeof(Snackbar2));
77+
78+
private static void OnIsActiveChanged(
79+
DependencyObject d, DependencyPropertyChangedEventArgs e)
80+
{
81+
var instance = d as Snackbar2;
82+
var args = new RoutedPropertyChangedEventArgs<bool>(
83+
(bool) e.OldValue,
84+
(bool) e.NewValue) {RoutedEvent = IsActiveChangedEvent };
85+
instance?.RaiseEvent(args);
6586
}
6687

6788
public static readonly RoutedEvent DeactivateStoryboardCompletedEvent =
@@ -123,6 +144,8 @@ private TimeSpan GetStoryboardResourceDuration(string resourceName)
123144

124145
private static void IsActivePropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
125146
{
147+
OnIsActiveChanged(dependencyObject, dependencyPropertyChangedEventArgs);
148+
126149
if ((bool)dependencyPropertyChangedEventArgs.NewValue) return;
127150

128151
var snackbar = (Snackbar2)dependencyObject;
@@ -148,51 +171,6 @@ private static void DeactivateStoryboardDispatcherTimerOnTick(object sender, Eve
148171
}
149172

150173

151-
[TypeConverter(typeof(SnackbarMessageTypeConverter))]
152-
public class SnackbarMessage : ContentControl
153-
{
154-
static SnackbarMessage()
155-
{
156-
DefaultStyleKeyProperty.OverrideMetadata(typeof(SnackbarMessage), new FrameworkPropertyMetadata(typeof(SnackbarMessage)));
157-
}
158-
159-
public static readonly DependencyProperty ActionContentProperty = DependencyProperty.Register(
160-
"ActionContent", typeof(object), typeof(SnackbarMessage), new PropertyMetadata(default(object)));
161-
162-
public object ActionContent
163-
{
164-
get { return (object) GetValue(ActionContentProperty); }
165-
set { SetValue(ActionContentProperty, value); }
166-
}
167-
168-
public static readonly DependencyProperty ActionContentTemplateProperty = DependencyProperty.Register(
169-
"ActionContentTemplate", typeof(DataTemplate), typeof(SnackbarMessage), new PropertyMetadata(default(DataTemplate)));
170-
171-
public DataTemplate ActionContentTemplate
172-
{
173-
get { return (DataTemplate) GetValue(ActionContentTemplateProperty); }
174-
set { SetValue(ActionContentTemplateProperty, value); }
175-
}
176-
177-
public static readonly DependencyProperty ActionContentStringFormatProperty = DependencyProperty.Register(
178-
"ActionContentStringFormat", typeof(string ), typeof(SnackbarMessage), new PropertyMetadata(default(string )));
179-
180-
public string ActionContentStringFormat
181-
{
182-
get { return (string ) GetValue(ActionContentStringFormatProperty); }
183-
set { SetValue(ActionContentStringFormatProperty, value); }
184-
}
185-
186-
public static readonly DependencyProperty ActionContentTemplateSelectorProperty = DependencyProperty.Register(
187-
"ActionContentTemplateSelector", typeof(DataTemplateSelector), typeof(SnackbarMessage), new PropertyMetadata(default(DataTemplateSelector)));
188-
189-
public DataTemplateSelector ActionContentTemplateSelector
190-
{
191-
get { return (DataTemplateSelector) GetValue(ActionContentTemplateSelectorProperty); }
192-
set { SetValue(ActionContentTemplateSelectorProperty, value); }
193-
}
194-
}
195-
196174
/// <summary>
197175
/// Implements a <see cref="Snackbar"/> inspired by the Material Design specs (https://material.google.com/components/snackbars-toasts.html).
198176
/// </summary>
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
using System;
2+
using System.ComponentModel;
3+
using System.Windows;
4+
using System.Windows.Controls;
5+
using System.Windows.Controls.Primitives;
6+
using System.Windows.Input;
7+
using MaterialDesignThemes.Wpf.Converters;
8+
9+
namespace MaterialDesignThemes.Wpf
10+
{
11+
/// <summary>
12+
/// Defines the content of a message within a <see cref="Snackbar2"/>. Primary content should be set via the
13+
/// standard <see cref="SnackbarMessage.Content"/> property. Where an action is allowed, content
14+
/// can be provided in <see cref="SnackbarMessage.ActionContent"/>. Standard button properties are
15+
/// provided for actions, includiing <see cref="SnackbarMessage.ActionCommand"/>.
16+
/// </summary>
17+
[TypeConverter(typeof(SnackbarMessageTypeConverter))]
18+
[TemplatePart(Name = ActionButtonPartName, Type = typeof(ButtonBase))]
19+
public class SnackbarMessage : ContentControl
20+
{
21+
public const string ActionButtonPartName = "PART_ActionButton";
22+
private Action _templateCleanupAction = () => {};
23+
24+
static SnackbarMessage()
25+
{
26+
DefaultStyleKeyProperty.OverrideMetadata(typeof(SnackbarMessage), new FrameworkPropertyMetadata(typeof(SnackbarMessage)));
27+
}
28+
29+
public static readonly DependencyProperty ActionCommandProperty = DependencyProperty.Register(
30+
"ActionCommand", typeof(ICommand), typeof(SnackbarMessage), new PropertyMetadata(default(ICommand)));
31+
32+
public ICommand ActionCommand
33+
{
34+
get { return (ICommand) GetValue(ActionCommandProperty); }
35+
set { SetValue(ActionCommandProperty, value); }
36+
}
37+
38+
public static readonly DependencyProperty ActionCommandParameterProperty = DependencyProperty.Register(
39+
"ActionCommandParameter", typeof(object), typeof(SnackbarMessage), new PropertyMetadata(default(object)));
40+
41+
public object ActionCommandParameter
42+
{
43+
get { return (object) GetValue(ActionCommandParameterProperty); }
44+
set { SetValue(ActionCommandParameterProperty, value); }
45+
}
46+
47+
public static readonly DependencyProperty ActionContentProperty = DependencyProperty.Register(
48+
"ActionContent", typeof(object), typeof(SnackbarMessage), new PropertyMetadata(default(object)));
49+
50+
public object ActionContent
51+
{
52+
get { return (object) GetValue(ActionContentProperty); }
53+
set { SetValue(ActionContentProperty, value); }
54+
}
55+
56+
public static readonly DependencyProperty ActionContentTemplateProperty = DependencyProperty.Register(
57+
"ActionContentTemplate", typeof(DataTemplate), typeof(SnackbarMessage), new PropertyMetadata(default(DataTemplate)));
58+
59+
public DataTemplate ActionContentTemplate
60+
{
61+
get { return (DataTemplate) GetValue(ActionContentTemplateProperty); }
62+
set { SetValue(ActionContentTemplateProperty, value); }
63+
}
64+
65+
public static readonly DependencyProperty ActionContentStringFormatProperty = DependencyProperty.Register(
66+
"ActionContentStringFormat", typeof(string ), typeof(SnackbarMessage), new PropertyMetadata(default(string )));
67+
68+
public string ActionContentStringFormat
69+
{
70+
get { return (string ) GetValue(ActionContentStringFormatProperty); }
71+
set { SetValue(ActionContentStringFormatProperty, value); }
72+
}
73+
74+
public static readonly DependencyProperty ActionContentTemplateSelectorProperty = DependencyProperty.Register(
75+
"ActionContentTemplateSelector", typeof(DataTemplateSelector), typeof(SnackbarMessage), new PropertyMetadata(default(DataTemplateSelector)));
76+
77+
public DataTemplateSelector ActionContentTemplateSelector
78+
{
79+
get { return (DataTemplateSelector) GetValue(ActionContentTemplateSelectorProperty); }
80+
set { SetValue(ActionContentTemplateSelectorProperty, value); }
81+
}
82+
83+
/// <summary>
84+
/// Event correspond to left mouse button click on the Action button.
85+
/// </summary>
86+
public static readonly RoutedEvent ActionClickEvent = EventManager.RegisterRoutedEvent("ActionClick",
87+
RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ButtonBase));
88+
89+
/// <summary>
90+
/// Add / Remove ActionClickEvent handler
91+
/// </summary>
92+
[Category("Behavior")]
93+
public event RoutedEventHandler ActionClick { add { AddHandler(ActionClickEvent, value); } remove { RemoveHandler(ActionClickEvent, value); } }
94+
95+
protected virtual void OnActionClick()
96+
{
97+
var newEvent = new RoutedEventArgs(ActionClickEvent, this);
98+
RaiseEvent(newEvent);
99+
}
100+
101+
public override void OnApplyTemplate()
102+
{
103+
_templateCleanupAction();
104+
105+
var buttonBase = GetTemplateChild(ActionButtonPartName) as ButtonBase;
106+
if (buttonBase != null)
107+
{
108+
buttonBase.Click += ButtonBaseOnClick;
109+
110+
_templateCleanupAction = () => buttonBase.Click -= ButtonBaseOnClick;
111+
}
112+
else
113+
_templateCleanupAction = () => { };
114+
115+
base.OnApplyTemplate();
116+
}
117+
118+
private void ButtonBaseOnClick(object sender, RoutedEventArgs routedEventArgs)
119+
{
120+
OnActionClick();
121+
}
122+
}
123+
}

0 commit comments

Comments
 (0)