From 844a1764fef2663d1d2b410f4b5edd604dd75d50 Mon Sep 17 00:00:00 2001 From: Odonno Date: Sat, 26 Aug 2017 11:29:22 +0200 Subject: [PATCH 01/21] feat(InAppNotifications): add events Opening, Opened and Dismissing --- .../InAppNotification.Events.cs | 35 +++++++++++++++++++ .../InAppNotification/InAppNotification.cs | 29 ++++++++++----- 2 files changed, 55 insertions(+), 9 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Events.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Events.cs index a0302e003de..2972d7734cb 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Events.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Events.cs @@ -20,6 +20,21 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls /// public partial class InAppNotification { + /// + /// Event raised when the notification is opening + /// + public event EventHandler Opening; + + /// + /// Event raised when the notification is opened + /// + public event EventHandler Opened; + + /// + /// Event raised when the notification is dismissing + /// + public event EventHandler Dismissing; + /// /// Event raised when the notification is dismissed /// @@ -29,5 +44,25 @@ private void DismissButton_Click(object sender, RoutedEventArgs e) { Dismiss(); } + + private void DismissTimer_Tick(object sender, object e) + { + Dismiss(); + _dismissTimer.Stop(); + } + + private void OpenAnimationTimer_Tick(object sender, object e) + { + _animationTimer.Stop(); + Opened?.Invoke(this, EventArgs.Empty); + _animationTimer.Tick -= OpenAnimationTimer_Tick; + } + + private void DismissAnimationTimer_Tick(object sender, object e) + { + _animationTimer.Stop(); + Dismissed?.Invoke(this, EventArgs.Empty); + _animationTimer.Tick -= DismissAnimationTimer_Tick; + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs index 9d7b0f2ddc0..0ad45daf5e8 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs @@ -24,7 +24,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls [TemplatePart(Name = DismissButtonPart, Type = typeof(Button))] public sealed partial class InAppNotification : ContentControl { - private DispatcherTimer _timer = new DispatcherTimer(); + private int _popupAnimationDuration = 100; // Duration of the popup animation (in milliseconds) + private DispatcherTimer _animationTimer = new DispatcherTimer(); + private DispatcherTimer _dismissTimer = new DispatcherTimer(); private Button _dismissButton; /// @@ -34,10 +36,7 @@ public InAppNotification() { DefaultStyleKey = typeof(InAppNotification); - _timer.Tick += (sender, e) => - { - Dismiss(); - }; + _dismissTimer.Tick += DismissTimer_Tick; } /// @@ -74,15 +73,21 @@ protected override void OnApplyTemplate() /// Displayed duration of the notification in ms (less or equal 0 means infinite duration) public void Show(int duration = 0) { - _timer.Stop(); + _animationTimer.Stop(); + _dismissTimer.Stop(); Visibility = Visibility.Visible; VisualStateManager.GoToState(this, StateContentVisible, true); + Opening?.Invoke(this, EventArgs.Empty); + + _animationTimer.Interval = TimeSpan.FromMilliseconds(_popupAnimationDuration); + _animationTimer.Tick += OpenAnimationTimer_Tick; + _animationTimer.Start(); if (duration > 0) { - _timer.Interval = TimeSpan.FromMilliseconds(duration); - _timer.Start(); + _dismissTimer.Interval = TimeSpan.FromMilliseconds(duration); + _dismissTimer.Start(); } } @@ -129,8 +134,14 @@ public void Dismiss() { if (Visibility == Visibility.Visible) { + _animationTimer.Stop(); + VisualStateManager.GoToState(this, StateContentCollapsed, true); - Dismissed?.Invoke(this, EventArgs.Empty); + Dismissing?.Invoke(this, EventArgs.Empty); + + _animationTimer.Interval = TimeSpan.FromMilliseconds(_popupAnimationDuration); + _animationTimer.Tick += DismissAnimationTimer_Tick; + _animationTimer.Start(); } } } From 4af5fb806bf38bc5cf45368e067b5e51ca8ed992 Mon Sep 17 00:00:00 2001 From: Odonno Date: Sat, 26 Aug 2017 11:35:17 +0200 Subject: [PATCH 02/21] docs(InAppNotifications): add docs on new events --- docs/controls/InAppNotification.md | 35 +++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/docs/controls/InAppNotification.md b/docs/controls/InAppNotification.md index 34ebc09886c..7b1b915c215 100644 --- a/docs/controls/InAppNotification.md +++ b/docs/controls/InAppNotification.md @@ -88,9 +88,42 @@ To hide it, simply set the property to `ShowDismissButton="False"`. ## Events +### Opening + +This event is raised when the system or your user started to open of the notification. + +```c# +private void InAppNotification_OnOpening(object sender, EventArgs e) +{ + // TODO +} +``` + +### Opened + +This event is raised when the notification is fully opened (after open animation). + +```c# +private void InAppNotification_OnOpened(object sender, EventArgs e) +{ + // TODO +} +``` + +### Dismissing + +This event is raised when the system or your user started to dismiss the notification. + +```c# +private void InAppNotification_OnDismissing(object sender, EventArgs e) +{ + // TODO +} +``` + ### Dismissed -This event is raised when the system or your user dismissed the notification. +This event is raised when the notification is fully dismissed (after dismiss animation). ```c# private void InAppNotification_OnDismissed(object sender, EventArgs e) From 348ab1c47ef9ffac52e4c23cec6ecc6d8ab71f5a Mon Sep 17 00:00:00 2001 From: Odonno Date: Sat, 26 Aug 2017 12:09:33 +0200 Subject: [PATCH 03/21] feat(InAppNotifications): add details on Dismissing event args --- .../InAppNotification.Events.cs | 6 +-- .../InAppNotification/InAppNotification.cs | 11 ++++- .../InAppNotificationDismissKind.cs | 27 ++++++++++++ .../InAppNotificationDismissingEventArgs.cs | 43 +++++++++++++++++++ .../Microsoft.Toolkit.Uwp.UI.Controls.csproj | 2 + docs/controls/InAppNotification.md | 10 ++++- 6 files changed, 94 insertions(+), 5 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationDismissKind.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationDismissingEventArgs.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Events.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Events.cs index 2972d7734cb..13a71bb02d1 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Events.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Events.cs @@ -33,7 +33,7 @@ public partial class InAppNotification /// /// Event raised when the notification is dismissing /// - public event EventHandler Dismissing; + public event InAppNotificationDismissingEventHandler Dismissing; /// /// Event raised when the notification is dismissed @@ -42,12 +42,12 @@ public partial class InAppNotification private void DismissButton_Click(object sender, RoutedEventArgs e) { - Dismiss(); + Dismiss(InAppNotificationDismissKind.User); } private void DismissTimer_Tick(object sender, object e) { - Dismiss(); + Dismiss(InAppNotificationDismissKind.Timeout); _dismissTimer.Stop(); } diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs index 0ad45daf5e8..c5bab9c48ff 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs @@ -131,13 +131,22 @@ public void Show(DataTemplate dataTemplate, int duration = 0) /// Dismiss the notification /// public void Dismiss() + { + Dismiss(InAppNotificationDismissKind.User); + } + + /// + /// Dismiss the notification + /// + /// Kind of action that triggered dismiss event + private void Dismiss(InAppNotificationDismissKind dismissKind) { if (Visibility == Visibility.Visible) { _animationTimer.Stop(); VisualStateManager.GoToState(this, StateContentCollapsed, true); - Dismissing?.Invoke(this, EventArgs.Empty); + Dismissing?.Invoke(this, new InAppNotificationDismissingEventArgs(dismissKind)); _animationTimer.Interval = TimeSpan.FromMilliseconds(_popupAnimationDuration); _animationTimer.Tick += DismissAnimationTimer_Tick; diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationDismissKind.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationDismissKind.cs new file mode 100644 index 00000000000..198186256f5 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationDismissKind.cs @@ -0,0 +1,27 @@ +// ****************************************************************** +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH +// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE. +// ****************************************************************** + +namespace Microsoft.Toolkit.Uwp.UI.Controls +{ + public enum InAppNotificationDismissKind + { + /// + /// When user explicitly dismissed the notification. + /// + User = 1, + + /// + /// When the system dismissed the notification after timeout. + /// + Timeout = 2 + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationDismissingEventArgs.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationDismissingEventArgs.cs new file mode 100644 index 00000000000..5c77f397093 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationDismissingEventArgs.cs @@ -0,0 +1,43 @@ +// ****************************************************************** +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH +// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE. +// ****************************************************************** + +using System; + +namespace Microsoft.Toolkit.Uwp.UI.Controls +{ + /// + /// A delegate for dismissing. + /// + /// The sender. + /// The event arguments. + public delegate void InAppNotificationDismissingEventHandler(object sender, InAppNotificationDismissingEventArgs e); + + /// + /// Provides data for the Dismissing event. + /// + public class InAppNotificationDismissingEventArgs : EventArgs + { + /// + /// Initializes a new instance of the class. + /// + /// Dismiss kind that triggered the dismissing event + public InAppNotificationDismissingEventArgs(InAppNotificationDismissKind dismissKind) + { + DismissKind = dismissKind; + } + + /// + /// Gets the kind of action for the dismissing event. + /// + public InAppNotificationDismissKind DismissKind { get; private set; } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/Microsoft.Toolkit.Uwp.UI.Controls.csproj b/Microsoft.Toolkit.Uwp.UI.Controls/Microsoft.Toolkit.Uwp.UI.Controls.csproj index f765b1113c8..40f27a929ff 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/Microsoft.Toolkit.Uwp.UI.Controls.csproj +++ b/Microsoft.Toolkit.Uwp.UI.Controls/Microsoft.Toolkit.Uwp.UI.Controls.csproj @@ -74,6 +74,8 @@ + + diff --git a/docs/controls/InAppNotification.md b/docs/controls/InAppNotification.md index 7b1b915c215..a0a6048737f 100644 --- a/docs/controls/InAppNotification.md +++ b/docs/controls/InAppNotification.md @@ -115,9 +115,17 @@ private void InAppNotification_OnOpened(object sender, EventArgs e) This event is raised when the system or your user started to dismiss the notification. ```c# -private void InAppNotification_OnDismissing(object sender, EventArgs e) +private void InAppNotification_OnDismissing(object sender, InAppNotificationDismissingEventArgs e) { // TODO + if (e.DismissKind == InAppNotificationDismissKind.User) + { + // When the user asked to dismiss the notification + } + if (e.DismissKind == InAppNotificationDismissKind.Timeout) + { + // When the notification is dismissed after timeout + } } ``` From 45140047b850cd3068f0c92d6f92c2e4e70d8bfd Mon Sep 17 00:00:00 2001 From: Odonno Date: Sun, 27 Aug 2017 22:27:23 +0200 Subject: [PATCH 04/21] feat(InAppNotifications): improve animations --- .../InAppNotificationXaml.bind | 10 +- .../InAppNotification.Properties.cs | 163 +++++++++++++++++- .../InAppNotification/InAppNotification.cs | 7 +- .../InAppNotification/InAppNotification.xaml | 29 +++- 4 files changed, 195 insertions(+), 14 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/InAppNotification/InAppNotificationXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/InAppNotification/InAppNotificationXaml.bind index 4bc98c5558c..139aa776efd 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/InAppNotification/InAppNotificationXaml.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/InAppNotification/InAppNotificationXaml.bind @@ -278,7 +278,10 @@ + ShowDismissButton="@[ShowDismissButton:Bool:True]" + AnimationDuration="@[AnimationDuration:String:100]" + VerticalOffset="@[VerticalOffset:String:100]" + HorizontalOffset="@[HorizontalOffset:String:0]" /> + RenderTransformOrigin="0.5,0" + AnimationDuration="@[AnimationDuration:String:100]" + VerticalOffset="@[VerticalOffset:String:100]" + HorizontalOffset="@[HorizontalOffset:String:0]"> diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Properties.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Properties.cs index fa765067d6a..1720a351cf5 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Properties.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Properties.cs @@ -10,7 +10,9 @@ // THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE. // ****************************************************************** +using System; using Windows.UI.Xaml; +using Windows.UI.Xaml.Media.Animation; namespace Microsoft.Toolkit.Uwp.UI.Controls { @@ -25,6 +27,24 @@ public partial class InAppNotification public static readonly DependencyProperty ShowDismissButtonProperty = DependencyProperty.Register(nameof(ShowDismissButton), typeof(bool), typeof(InAppNotification), new PropertyMetadata(true, OnShowDismissButtonChanged)); + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty AnimationDurationProperty = + DependencyProperty.Register(nameof(AnimationDuration), typeof(int), typeof(InAppNotification), new PropertyMetadata(100, OnAnimationDurationChanged)); + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty VerticalOffsetProperty = + DependencyProperty.Register(nameof(VerticalOffset), typeof(double), typeof(InAppNotification), new PropertyMetadata(100, OnVerticalOffsetChanged)); + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty HorizontalOffsetProperty = + DependencyProperty.Register(nameof(HorizontalOffset), typeof(double), typeof(InAppNotification), new PropertyMetadata(0, OnHorizontalOffsetChanged)); + /// /// Gets or sets a value indicating whether to show the Dismiss button of the control. /// @@ -34,16 +54,155 @@ public bool ShowDismissButton set { SetValue(ShowDismissButtonProperty, value); } } + /// + /// Gets or sets a value indicating the duration of the popup animation (in milliseconds). + /// + public int AnimationDuration + { + get { return (int)GetValue(AnimationDurationProperty); } + set { SetValue(AnimationDurationProperty, value); } + } + + /// + /// Gets or sets a value indicating the vertical offset of the popup animation. + /// + public double VerticalOffset + { + get { return (double)GetValue(VerticalOffsetProperty); } + set { SetValue(VerticalOffsetProperty, value); } + } + + /// + /// Gets or sets a value indicating the horizontal offset of the popup animation. + /// + public double HorizontalOffset + { + get { return (double)GetValue(HorizontalOffsetProperty); } + set { SetValue(HorizontalOffsetProperty, value); } + } + private static void OnShowDismissButtonChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var inApNotification = d as InAppNotification; - bool showDismissButton = (bool)e.NewValue; - if (inApNotification._dismissButton != null) { + bool showDismissButton = (bool)e.NewValue; inApNotification._dismissButton.Visibility = showDismissButton ? Visibility.Visible : Visibility.Collapsed; } } + + private static void OnAnimationDurationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var inApNotification = d as InAppNotification; + + if (inApNotification._visualStateGroup != null) + { + int duration = (int)e.NewValue; + var keyTimeFromAnimationDuration = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(duration)); + + foreach (var state in inApNotification._visualStateGroup.States) + { + foreach (var timeline in state.Storyboard.Children) + { + if (timeline is DoubleAnimationUsingKeyFrames daukf) + { + var keyFramesCount = daukf.KeyFrames.Count; + if (keyFramesCount > 1) + { + daukf.KeyFrames[keyFramesCount - 1].KeyTime = keyTimeFromAnimationDuration; + } + } + + if (timeline is ObjectAnimationUsingKeyFrames oaukf) + { + var keyFramesCount = oaukf.KeyFrames.Count; + if (keyFramesCount > 1) + { + oaukf.KeyFrames[keyFramesCount - 1].KeyTime = keyTimeFromAnimationDuration; + } + } + } + } + } + } + + private static void OnVerticalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var inApNotification = d as InAppNotification; + + if (inApNotification._visualStateGroup != null) + { + double verticalOffset = (double)e.NewValue; + + foreach (var state in inApNotification._visualStateGroup.States) + { + foreach (var timeline in state.Storyboard.Children) + { + if (timeline is DoubleAnimationUsingKeyFrames daukf) + { + var targetProperty = (string)timeline.GetValue(Storyboard.TargetPropertyProperty); + + if (targetProperty == "(UIElement.RenderTransform).(CompositeTransform.TranslateY)") + { + var keyFramesCount = daukf.KeyFrames.Count; + + if (keyFramesCount > 1) + { + if (state.Name == "Visible") + { + daukf.KeyFrames[0].Value = verticalOffset; + } + + if (state.Name == "Collapsed") + { + daukf.KeyFrames[keyFramesCount - 1].Value = verticalOffset; + } + } + } + } + } + } + } + } + + private static void OnHorizontalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var inApNotification = d as InAppNotification; + + if (inApNotification._visualStateGroup != null) + { + double horizontalOffset = (double)e.NewValue; + + foreach (var state in inApNotification._visualStateGroup.States) + { + foreach (var timeline in state.Storyboard.Children) + { + if (timeline is DoubleAnimationUsingKeyFrames daukf) + { + var targetProperty = (string)timeline.GetValue(Storyboard.TargetPropertyProperty); + + if (targetProperty == "(UIElement.RenderTransform).(CompositeTransform.TranslateX)") + { + var keyFramesCount = daukf.KeyFrames.Count; + + if (keyFramesCount > 1) + { + if (state.Name == "Visible") + { + daukf.KeyFrames[0].Value = horizontalOffset; + } + + if (state.Name == "Collapsed") + { + daukf.KeyFrames[keyFramesCount - 1].Value = horizontalOffset; + } + } + } + } + } + } + } + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs index c5bab9c48ff..f9a82a52d4d 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs @@ -24,10 +24,10 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls [TemplatePart(Name = DismissButtonPart, Type = typeof(Button))] public sealed partial class InAppNotification : ContentControl { - private int _popupAnimationDuration = 100; // Duration of the popup animation (in milliseconds) private DispatcherTimer _animationTimer = new DispatcherTimer(); private DispatcherTimer _dismissTimer = new DispatcherTimer(); private Button _dismissButton; + private VisualStateGroup _visualStateGroup; /// /// Initializes a new instance of the class. @@ -48,6 +48,7 @@ protected override void OnApplyTemplate() } _dismissButton = (Button)GetTemplateChild(DismissButtonPart); + _visualStateGroup = (VisualStateGroup)GetTemplateChild(GroupContent); if (_dismissButton != null) { @@ -80,7 +81,7 @@ public void Show(int duration = 0) VisualStateManager.GoToState(this, StateContentVisible, true); Opening?.Invoke(this, EventArgs.Empty); - _animationTimer.Interval = TimeSpan.FromMilliseconds(_popupAnimationDuration); + _animationTimer.Interval = TimeSpan.FromMilliseconds(AnimationDuration); _animationTimer.Tick += OpenAnimationTimer_Tick; _animationTimer.Start(); @@ -148,7 +149,7 @@ private void Dismiss(InAppNotificationDismissKind dismissKind) VisualStateManager.GoToState(this, StateContentCollapsed, true); Dismissing?.Invoke(this, new InAppNotificationDismissingEventArgs(dismissKind)); - _animationTimer.Interval = TimeSpan.FromMilliseconds(_popupAnimationDuration); + _animationTimer.Interval = TimeSpan.FromMilliseconds(AnimationDuration); _animationTimer.Tick += DismissAnimationTimer_Tick; _animationTimer.Start(); } diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.xaml b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.xaml index 8f734cd75b2..d251a7b3ab5 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.xaml +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.xaml @@ -89,12 +89,20 @@ - - - + + + - + + + + + + Visible @@ -111,9 +119,16 @@ - - - + + + + + + + + From 13dbd449dca6b26f799529bfc5ec1279d1d69860 Mon Sep 17 00:00:00 2001 From: Odonno Date: Mon, 28 Aug 2017 22:50:27 +0200 Subject: [PATCH 05/21] refactor(InAppNotifications): split styles into separate files --- .../InAppNotificationPage.xaml | 5 + .../InAppNotificationXaml.bind | 30 +-- .../InAppNotification/InAppNotification.xaml | 166 +---------------- .../Styles/MSEdgeNotificationStyle.xaml | 174 ++++++++++++++++++ .../Styles/VSCodeNotificationStyle.xaml | 154 ++++++++++++++++ .../Microsoft.Toolkit.Uwp.UI.Controls.csproj | 10 + 6 files changed, 356 insertions(+), 183 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/Styles/MSEdgeNotificationStyle.xaml create mode 100644 Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/Styles/VSCodeNotificationStyle.xaml diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/InAppNotification/InAppNotificationPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/InAppNotification/InAppNotificationPage.xaml index 313e7772199..6ced1a4a670 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/InAppNotification/InAppNotificationPage.xaml +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/InAppNotification/InAppNotificationPage.xaml @@ -11,6 +11,11 @@ + + + + + + + + + diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/Styles/MSEdgeNotificationStyle.xaml b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/Styles/MSEdgeNotificationStyle.xaml new file mode 100644 index 00000000000..b7d3ba6864f --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/Styles/MSEdgeNotificationStyle.xaml @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Visible + + + + + Collapsed + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + public void Dismiss() { - Dismiss(InAppNotificationDismissKind.User); + Dismiss(InAppNotificationDismissKind.Programmatic); } /// diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationDismissKind.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationDismissKind.cs index 198186256f5..839faace303 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationDismissKind.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationDismissKind.cs @@ -14,14 +14,19 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls { public enum InAppNotificationDismissKind { + /// + /// When the system dismissed the notification. + /// + Programmatic, + /// /// When user explicitly dismissed the notification. /// - User = 1, + User, /// /// When the system dismissed the notification after timeout. /// - Timeout = 2 + Timeout } } diff --git a/docs/controls/InAppNotification.md b/docs/controls/InAppNotification.md index a0a6048737f..2a5d468f64f 100644 --- a/docs/controls/InAppNotification.md +++ b/docs/controls/InAppNotification.md @@ -90,7 +90,7 @@ To hide it, simply set the property to `ShowDismissButton="False"`. ### Opening -This event is raised when the system or your user started to open of the notification. +This event is raised just before the notification starts to open. ```c# private void InAppNotification_OnOpening(object sender, EventArgs e) From a8965f666acf84283f232e21552aa4d3262823a1 Mon Sep 17 00:00:00 2001 From: Odonno Date: Mon, 28 Aug 2017 23:33:57 +0200 Subject: [PATCH 07/21] feat(InAppNotifications): add ability to cancel the opening/closing --- .../InAppNotification.Events.cs | 2 +- .../InAppNotification/InAppNotification.cs | 18 +++++++- .../InAppNotificationDismissingEventArgs.cs | 5 +++ .../InAppNotificationOpeningEventArgs.cs | 41 +++++++++++++++++++ 4 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationOpeningEventArgs.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Events.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Events.cs index 13a71bb02d1..a4a5c7a12c3 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Events.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Events.cs @@ -23,7 +23,7 @@ public partial class InAppNotification /// /// Event raised when the notification is opening /// - public event EventHandler Opening; + public event InAppNotificationOpeningEventHandler Opening; /// /// Event raised when the notification is opened diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs index 7c20016f7a1..fbb55f72f3b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs @@ -77,7 +77,14 @@ public void Show(int duration = 0) _animationTimer.Stop(); _dismissTimer.Stop(); - Opening?.Invoke(this, EventArgs.Empty); + var eventArgs = new InAppNotificationOpeningEventArgs(); + Opening?.Invoke(this, eventArgs); + + if (eventArgs.Cancel) + { + return; + } + Visibility = Visibility.Visible; VisualStateManager.GoToState(this, StateContentVisible, true); @@ -146,8 +153,15 @@ private void Dismiss(InAppNotificationDismissKind dismissKind) { _animationTimer.Stop(); + var eventArgs = new InAppNotificationDismissingEventArgs(dismissKind); + Dismissing?.Invoke(this, eventArgs); + + if (eventArgs.Cancel) + { + return; + } + VisualStateManager.GoToState(this, StateContentCollapsed, true); - Dismissing?.Invoke(this, new InAppNotificationDismissingEventArgs(dismissKind)); _animationTimer.Interval = TimeSpan.FromMilliseconds(AnimationDuration); _animationTimer.Tick += DismissAnimationTimer_Tick; diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationDismissingEventArgs.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationDismissingEventArgs.cs index 5c77f397093..b2c0e35564f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationDismissingEventArgs.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationDismissingEventArgs.cs @@ -39,5 +39,10 @@ public InAppNotificationDismissingEventArgs(InAppNotificationDismissKind dismiss /// Gets the kind of action for the dismissing event. /// public InAppNotificationDismissKind DismissKind { get; private set; } + + /// + /// Gets or sets a value indicating whether the notification should be dismissed. + /// + public bool Cancel { get; set; } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationOpeningEventArgs.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationOpeningEventArgs.cs new file mode 100644 index 00000000000..7a33b51b732 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationOpeningEventArgs.cs @@ -0,0 +1,41 @@ +// ****************************************************************** +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH +// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE. +// ****************************************************************** + +using System; + +namespace Microsoft.Toolkit.Uwp.UI.Controls +{ + /// + /// A delegate for opening. + /// + /// The sender. + /// The event arguments. + public delegate void InAppNotificationOpeningEventHandler(object sender, InAppNotificationOpeningEventArgs e); + + /// + /// Provides data for the Dismissing event. + /// + public class InAppNotificationOpeningEventArgs : EventArgs + { + /// + /// Initializes a new instance of the class. + /// + public InAppNotificationOpeningEventArgs() + { + } + + /// + /// Gets or sets a value indicating whether the notification should be opened. + /// + public bool Cancel { get; set; } + } +} From 27539f51db5e650cad2967f859c9844cd822d429 Mon Sep 17 00:00:00 2001 From: Odonno Date: Tue, 29 Aug 2017 19:50:04 +0200 Subject: [PATCH 08/21] docs(InAppNotifications): update animation part --- .../Styles/VSCodeNotificationStyle.xaml | 5 ++-- docs/controls/InAppNotification.md | 23 +++++++------------ 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/Styles/VSCodeNotificationStyle.xaml b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/Styles/VSCodeNotificationStyle.xaml index 5ae2a7c6ab5..1541861b7c9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/Styles/VSCodeNotificationStyle.xaml +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/Styles/VSCodeNotificationStyle.xaml @@ -60,6 +60,7 @@ + @@ -78,7 +79,7 @@ - + - + diff --git a/docs/controls/InAppNotification.md b/docs/controls/InAppNotification.md index 2a5d468f64f..afd63fd8664 100644 --- a/docs/controls/InAppNotification.md +++ b/docs/controls/InAppNotification.md @@ -93,7 +93,7 @@ To hide it, simply set the property to `ShowDismissButton="False"`. This event is raised just before the notification starts to open. ```c# -private void InAppNotification_OnOpening(object sender, EventArgs e) +private void InAppNotification_OnOpening(object sender, InAppNotificationOpeningEventArgs e) { // TODO } @@ -142,23 +142,16 @@ private void InAppNotification_OnDismissed(object sender, EventArgs e) ## Animation -By default, the popup animation of the control is a bottom to top animation. You can update the popup animation using the `RenderTransformOrigin` property of the control. See examples: +The default animation are set on each Notification Style. +You can update the animation using three distinct properties : -```xml - - - -``` - -The default value (X: 0.5, Y:1) will show popup animation from bottom to top. +* `AnimationDuration` - duration of the popup animation (in milliseconds) +* `VerticalOffset` - vertical offset of the popup animation +* `HorizontalOffset` - horizontal offset of the popup animation -```xml - - - -``` +## Styling -An alternate version of the popup animation (used by the vscode-like notification) will start from top to bottom. +TODO ## Example Code From 562ac87f69b5b1f8cb290b985e8f52957ae2b88a Mon Sep 17 00:00:00 2001 From: Odonno Date: Tue, 29 Aug 2017 20:33:36 +0200 Subject: [PATCH 09/21] docs(InAppNotifications): add styling part --- .../InAppNotificationXaml.bind | 2 - .../InAppNotification/InAppNotification.xaml | 10 +++++ .../Styles/MSEdgeNotificationStyle.xaml | 31 +++++++------- .../Microsoft.Toolkit.Uwp.UI.Controls.csproj | 1 + docs/controls/InAppNotification.md | 41 ++++++++++++++++++- 5 files changed, 66 insertions(+), 19 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/InAppNotification/InAppNotificationXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/InAppNotification/InAppNotificationXaml.bind index bdbb3bd0726..65da7d5f5e4 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/InAppNotification/InAppNotificationXaml.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/InAppNotification/InAppNotificationXaml.bind @@ -10,7 +10,6 @@ - @@ -282,7 +281,6 @@ + + + + + + + + + + diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/Styles/MSEdgeNotificationStyle.xaml b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/Styles/MSEdgeNotificationStyle.xaml index b7d3ba6864f..8088252e3f0 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/Styles/MSEdgeNotificationStyle.xaml +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/Styles/MSEdgeNotificationStyle.xaml @@ -67,22 +67,6 @@ - - @@ -171,4 +155,19 @@ + diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/Microsoft.Toolkit.Uwp.UI.Controls.csproj b/Microsoft.Toolkit.Uwp.UI.Controls/Microsoft.Toolkit.Uwp.UI.Controls.csproj index 9da5e4717e8..5e5aaf4a388 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/Microsoft.Toolkit.Uwp.UI.Controls.csproj +++ b/Microsoft.Toolkit.Uwp.UI.Controls/Microsoft.Toolkit.Uwp.UI.Controls.csproj @@ -76,6 +76,7 @@ + diff --git a/docs/controls/InAppNotification.md b/docs/controls/InAppNotification.md index afd63fd8664..0e8fef5052a 100644 --- a/docs/controls/InAppNotification.md +++ b/docs/controls/InAppNotification.md @@ -151,7 +151,46 @@ You can update the animation using three distinct properties : ## Styling -TODO +### Using styles + +The In App Notification control is designed to support multiple styles. +The default style applied is the Microsoft Edge-like notification. ?? +Other styles have been added to the Toolkit so you can easily switch to another of your favorite In App Notification styles. + +Here is the list of existing styles : +* [Microsoft Edge notification style](../..//Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/Styles/MSEdgeNotificationStyle.xaml) +* [Visual Studio Code notification style](../..//Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/Styles/VSCodeNotificationStyle.xaml) + +If you want to use another style than the default one, please follow the example below : + +1. Import external styles in your resources + +```xml + + + + + + + +``` + +2. Apply the `Style` + +```xml + +``` + +### Adding styles + +If you want to add styles to the Toolkit, please follow these steps : + +1. Create a `ResourceDictionary` file under `InAppNotification/Styles/` folder of `Microsoft.Toolkit.Uwp.UI.Controls` project +2. Create a new `Style` with `TargetType="local:InAppNotification"` +3. Create a new `ControlTemplate` with `TargetType="local:InAppNotification"` and add a `ContentPresenter` inside the Template +4. Do not forget to set the `Template` property inside your `Style` resource ## Example Code From 9676d3b86cdd76db694706d906c7b80d4b295bb8 Mon Sep 17 00:00:00 2001 From: Odonno Date: Tue, 29 Aug 2017 22:44:07 +0200 Subject: [PATCH 10/21] docs(InAppNotifications): fix typos and improve animation property description --- docs/controls/InAppNotification.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/controls/InAppNotification.md b/docs/controls/InAppNotification.md index 0e8fef5052a..164a86d1ab2 100644 --- a/docs/controls/InAppNotification.md +++ b/docs/controls/InAppNotification.md @@ -145,16 +145,18 @@ private void InAppNotification_OnDismissed(object sender, EventArgs e) The default animation are set on each Notification Style. You can update the animation using three distinct properties : -* `AnimationDuration` - duration of the popup animation (in milliseconds) -* `VerticalOffset` - vertical offset of the popup animation -* `HorizontalOffset` - horizontal offset of the popup animation +| Animation properties | Type | Description | +| -- | -- | -- | +| `AnimationDuration` | int | Duration of the popup animation in milliseconds | +| `VerticalOffset` | double | Vertical offset of the popup animation | +| `HorizontalOffset` | double | Horizontal offset of the popup animation | ## Styling ### Using styles -The In App Notification control is designed to support multiple styles. -The default style applied is the Microsoft Edge-like notification. ?? +The in-app notification control is designed to support multiple styles. +The default style applied is the Microsoft Edge-like notification. Other styles have been added to the Toolkit so you can easily switch to another of your favorite In App Notification styles. Here is the list of existing styles : From ad14b9b0b54e45507ec7660e0249b5b474273289 Mon Sep 17 00:00:00 2001 From: Odonno Date: Wed, 30 Aug 2017 20:21:13 +0200 Subject: [PATCH 11/21] fix(InAppNotifications): update animation properties on the control when first initialized --- .../InAppNotification.Properties.cs | 103 +--------------- .../InAppNotification/InAppNotification.cs | 110 ++++++++++++++++++ 2 files changed, 116 insertions(+), 97 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Properties.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Properties.cs index 1720a351cf5..a4c557dbae7 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Properties.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Properties.cs @@ -10,9 +10,7 @@ // THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE. // ****************************************************************** -using System; using Windows.UI.Xaml; -using Windows.UI.Xaml.Media.Animation; namespace Microsoft.Toolkit.Uwp.UI.Controls { @@ -96,113 +94,24 @@ private static void OnAnimationDurationChanged(DependencyObject d, DependencyPro { var inApNotification = d as InAppNotification; - if (inApNotification._visualStateGroup != null) - { - int duration = (int)e.NewValue; - var keyTimeFromAnimationDuration = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(duration)); - - foreach (var state in inApNotification._visualStateGroup.States) - { - foreach (var timeline in state.Storyboard.Children) - { - if (timeline is DoubleAnimationUsingKeyFrames daukf) - { - var keyFramesCount = daukf.KeyFrames.Count; - if (keyFramesCount > 1) - { - daukf.KeyFrames[keyFramesCount - 1].KeyTime = keyTimeFromAnimationDuration; - } - } - - if (timeline is ObjectAnimationUsingKeyFrames oaukf) - { - var keyFramesCount = oaukf.KeyFrames.Count; - if (keyFramesCount > 1) - { - oaukf.KeyFrames[keyFramesCount - 1].KeyTime = keyTimeFromAnimationDuration; - } - } - } - } - } + int duration = (int)e.NewValue; + inApNotification.UpdateAnimationDuration(duration); } private static void OnVerticalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var inApNotification = d as InAppNotification; - if (inApNotification._visualStateGroup != null) - { - double verticalOffset = (double)e.NewValue; - - foreach (var state in inApNotification._visualStateGroup.States) - { - foreach (var timeline in state.Storyboard.Children) - { - if (timeline is DoubleAnimationUsingKeyFrames daukf) - { - var targetProperty = (string)timeline.GetValue(Storyboard.TargetPropertyProperty); - - if (targetProperty == "(UIElement.RenderTransform).(CompositeTransform.TranslateY)") - { - var keyFramesCount = daukf.KeyFrames.Count; - - if (keyFramesCount > 1) - { - if (state.Name == "Visible") - { - daukf.KeyFrames[0].Value = verticalOffset; - } - - if (state.Name == "Collapsed") - { - daukf.KeyFrames[keyFramesCount - 1].Value = verticalOffset; - } - } - } - } - } - } - } + double verticalOffset = (double)e.NewValue; + inApNotification.UpdateVerticalOffset(verticalOffset); } private static void OnHorizontalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var inApNotification = d as InAppNotification; - if (inApNotification._visualStateGroup != null) - { - double horizontalOffset = (double)e.NewValue; - - foreach (var state in inApNotification._visualStateGroup.States) - { - foreach (var timeline in state.Storyboard.Children) - { - if (timeline is DoubleAnimationUsingKeyFrames daukf) - { - var targetProperty = (string)timeline.GetValue(Storyboard.TargetPropertyProperty); - - if (targetProperty == "(UIElement.RenderTransform).(CompositeTransform.TranslateX)") - { - var keyFramesCount = daukf.KeyFrames.Count; - - if (keyFramesCount > 1) - { - if (state.Name == "Visible") - { - daukf.KeyFrames[0].Value = horizontalOffset; - } - - if (state.Name == "Collapsed") - { - daukf.KeyFrames[keyFramesCount - 1].Value = horizontalOffset; - } - } - } - } - } - } - } + double horizontalOffset = (double)e.NewValue; + inApNotification.UpdateHorizontalOffset(horizontalOffset); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs index fbb55f72f3b..c2a165b09b9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs @@ -13,6 +13,7 @@ using System; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Media.Animation; namespace Microsoft.Toolkit.Uwp.UI.Controls { @@ -56,6 +57,13 @@ protected override void OnApplyTemplate() _dismissButton.Click += DismissButton_Click; } + if (_visualStateGroup != null) + { + UpdateAnimationDuration(AnimationDuration); + UpdateVerticalOffset(VerticalOffset); + UpdateHorizontalOffset(HorizontalOffset); + } + if (Visibility == Visibility.Visible) { VisualStateManager.GoToState(this, StateContentVisible, true); @@ -168,5 +176,107 @@ private void Dismiss(InAppNotificationDismissKind dismissKind) _animationTimer.Start(); } } + + private void UpdateAnimationDuration(int duration) + { + if (_visualStateGroup != null) + { + var keyTimeFromAnimationDuration = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(duration)); + + foreach (var state in _visualStateGroup.States) + { + foreach (var timeline in state.Storyboard.Children) + { + if (timeline is DoubleAnimationUsingKeyFrames daukf) + { + var keyFramesCount = daukf.KeyFrames.Count; + if (keyFramesCount > 1) + { + daukf.KeyFrames[keyFramesCount - 1].KeyTime = keyTimeFromAnimationDuration; + } + } + + if (timeline is ObjectAnimationUsingKeyFrames oaukf) + { + var keyFramesCount = oaukf.KeyFrames.Count; + if (keyFramesCount > 1) + { + oaukf.KeyFrames[keyFramesCount - 1].KeyTime = keyTimeFromAnimationDuration; + } + } + } + } + } + } + + private void UpdateVerticalOffset(double verticalOffset) + { + if (_visualStateGroup != null) + { + foreach (var state in _visualStateGroup.States) + { + foreach (var timeline in state.Storyboard.Children) + { + if (timeline is DoubleAnimationUsingKeyFrames daukf) + { + var targetProperty = (string)timeline.GetValue(Storyboard.TargetPropertyProperty); + + if (targetProperty == "(UIElement.RenderTransform).(CompositeTransform.TranslateY)") + { + var keyFramesCount = daukf.KeyFrames.Count; + + if (keyFramesCount > 1) + { + if (state.Name == "Visible") + { + daukf.KeyFrames[0].Value = verticalOffset; + } + + if (state.Name == "Collapsed") + { + daukf.KeyFrames[keyFramesCount - 1].Value = verticalOffset; + } + } + } + } + } + } + } + } + + private void UpdateHorizontalOffset(double horizontalOffset) + { + if (_visualStateGroup != null) + { + foreach (var state in _visualStateGroup.States) + { + foreach (var timeline in state.Storyboard.Children) + { + if (timeline is DoubleAnimationUsingKeyFrames daukf) + { + var targetProperty = (string)timeline.GetValue(Storyboard.TargetPropertyProperty); + + if (targetProperty == "(UIElement.RenderTransform).(CompositeTransform.TranslateX)") + { + var keyFramesCount = daukf.KeyFrames.Count; + + if (keyFramesCount > 1) + { + if (state.Name == "Visible") + { + daukf.KeyFrames[0].Value = horizontalOffset; + } + + if (state.Name == "Collapsed") + { + daukf.KeyFrames[keyFramesCount - 1].Value = horizontalOffset; + } + } + } + } + } + } + } + } } } From 227619ae032b2baac4ac22657c7d31d550acafc4 Mon Sep 17 00:00:00 2001 From: Odonno Date: Thu, 31 Aug 2017 20:49:02 +0200 Subject: [PATCH 12/21] fix(InAppNotifications): add default values for animation in default template --- .../InAppNotification/InAppNotification.xaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.xaml b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.xaml index 7d1e172fd66..303938a5794 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.xaml +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.xaml @@ -22,6 +22,9 @@ + + + From 828c5172c8a2d0a7e440668d277ca44c5dd0043d Mon Sep 17 00:00:00 2001 From: Odonno Date: Sat, 30 Sep 2017 11:28:50 +0200 Subject: [PATCH 13/21] feat(InAppNotification): mark Dimiss events as obsolete and replace them with Close events --- .../InAppNotification.Events.cs | 14 ++++++ .../InAppNotification/InAppNotification.cs | 9 ++-- .../InAppNotificationClosingEventArgs.cs | 48 +++++++++++++++++++ docs/controls/InAppNotification.md | 12 ++--- 4 files changed, 74 insertions(+), 9 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationClosingEventArgs.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Events.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Events.cs index a4a5c7a12c3..714dc9d0811 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Events.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Events.cs @@ -11,6 +11,7 @@ // ****************************************************************** using System; +using Windows.Foundation.Metadata; using Windows.UI.Xaml; namespace Microsoft.Toolkit.Uwp.UI.Controls @@ -33,13 +34,25 @@ public partial class InAppNotification /// /// Event raised when the notification is dismissing /// + [Obsolete("Use Closing event instead.")] public event InAppNotificationDismissingEventHandler Dismissing; /// /// Event raised when the notification is dismissed /// + [Obsolete("Use Closed event instead.")] public event EventHandler Dismissed; + /// + /// Event raised when the notification is closing + /// + public event InAppNotificationClosingEventHandler Closing; + + /// + /// Event raised when the notification is closed + /// + public event EventHandler Closed; + private void DismissButton_Click(object sender, RoutedEventArgs e) { Dismiss(InAppNotificationDismissKind.User); @@ -62,6 +75,7 @@ private void DismissAnimationTimer_Tick(object sender, object e) { _animationTimer.Stop(); Dismissed?.Invoke(this, EventArgs.Empty); + Closed?.Invoke(this, EventArgs.Empty); _animationTimer.Tick -= DismissAnimationTimer_Tick; } } diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs index c2a165b09b9..5ea17c485a5 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs @@ -161,10 +161,13 @@ private void Dismiss(InAppNotificationDismissKind dismissKind) { _animationTimer.Stop(); - var eventArgs = new InAppNotificationDismissingEventArgs(dismissKind); - Dismissing?.Invoke(this, eventArgs); + var dismissingEventArgs = new InAppNotificationDismissingEventArgs(dismissKind); + Dismissing?.Invoke(this, dismissingEventArgs); - if (eventArgs.Cancel) + var closingEventArgs = new InAppNotificationClosingEventArgs(dismissKind); + Closing?.Invoke(this, closingEventArgs); + + if (dismissingEventArgs.Cancel || closingEventArgs.Cancel) { return; } diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationClosingEventArgs.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationClosingEventArgs.cs new file mode 100644 index 00000000000..1bad5d6e959 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationClosingEventArgs.cs @@ -0,0 +1,48 @@ +// ****************************************************************** +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH +// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE. +// ****************************************************************** + +using System; + +namespace Microsoft.Toolkit.Uwp.UI.Controls +{ + /// + /// A delegate for dismissing. + /// + /// The sender. + /// The event arguments. + public delegate void InAppNotificationClosingEventHandler(object sender, InAppNotificationClosingEventArgs e); + + /// + /// Provides data for the Dismissing event. + /// + public class InAppNotificationClosingEventArgs : EventArgs + { + /// + /// Initializes a new instance of the class. + /// + /// Dismiss kind that triggered the closing event + public InAppNotificationClosingEventArgs(InAppNotificationDismissKind dismissKind) + { + DismissKind = dismissKind; + } + + /// + /// Gets the kind of action for the closing event. + /// + public InAppNotificationDismissKind DismissKind { get; private set; } + + /// + /// Gets or sets a value indicating whether the notification should be closed. + /// + public bool Cancel { get; set; } + } +} diff --git a/docs/controls/InAppNotification.md b/docs/controls/InAppNotification.md index 8b1bd39dff5..4dd13c7d533 100644 --- a/docs/controls/InAppNotification.md +++ b/docs/controls/InAppNotification.md @@ -110,12 +110,12 @@ private void InAppNotification_OnOpened(object sender, EventArgs e) } ``` -### Dismissing +### Closing -This event is raised when the system or your user started to dismiss the notification. +This event is raised when the system or your user started to close the notification. ```c# -private void InAppNotification_OnDismissing(object sender, InAppNotificationDismissingEventArgs e) +private void InAppNotification_OnClosing(object sender, InAppNotificationDismissingEventArgs e) { // TODO if (e.DismissKind == InAppNotificationDismissKind.User) @@ -129,12 +129,12 @@ private void InAppNotification_OnDismissing(object sender, InAppNotificationDism } ``` -### Dismissed +### Closed -This event is raised when the notification is fully dismissed (after dismiss animation). +This event is raised when the notification is fully closed (after close animation). ```c# -private void InAppNotification_OnDismissed(object sender, EventArgs e) +private void InAppNotification_OnClosed(object sender, EventArgs e) { // TODO } From 99ccc7610e407872501c313be919dced797569c2 Mon Sep 17 00:00:00 2001 From: Nikola Metulev Date: Mon, 9 Oct 2017 14:58:29 -0700 Subject: [PATCH 14/21] Moved animation properties to template --- .../Common/TimeSpanConverter.cs | 40 +++++++ .../Controls/PropertyControl.xaml.cs | 20 ++++ .../Microsoft.Toolkit.Uwp.SampleApp.csproj | 1 + .../Models/PropertyDescriptor/PropertyKind.cs | 3 +- .../Models/Sample.cs | 31 +++++ .../InAppNotificationXaml.bind | 2 +- Microsoft.Toolkit.Uwp.SampleApp/readme.md | 1 + .../InAppNotification.AttachedProperties.cs | 54 +++++++++ .../InAppNotification.Properties.cs | 35 +----- .../InAppNotification/InAppNotification.cs | 113 +----------------- .../Styles/MSEdgeNotificationStyle.xaml | 16 +-- 11 files changed, 167 insertions(+), 149 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/Common/TimeSpanConverter.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.AttachedProperties.cs diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Common/TimeSpanConverter.cs b/Microsoft.Toolkit.Uwp.SampleApp/Common/TimeSpanConverter.cs new file mode 100644 index 00000000000..b79f8dd672d --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/Common/TimeSpanConverter.cs @@ -0,0 +1,40 @@ +// ****************************************************************** +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH +// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE. +// ****************************************************************** + +using System; +using Windows.UI.Xaml.Data; + +namespace Microsoft.Toolkit.Uwp.SampleApp.Common +{ + public class TimeSpanConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, string language) + { + if (value is TimeSpan tSpan) + { + return tSpan.TotalMilliseconds; + } + + return value; + } + + public object ConvertBack(object value, Type targetType, object parameter, string language) + { + if (value is double milliseconds) + { + return TimeSpan.FromMilliseconds(milliseconds); + } + + return TimeSpan.MinValue; + } + } +} diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Controls/PropertyControl.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/Controls/PropertyControl.xaml.cs index 8cf2bc5706d..e1cb0dbdc5e 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Controls/PropertyControl.xaml.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/Controls/PropertyControl.xaml.cs @@ -151,6 +151,26 @@ private void PropertyControl_OnDataContextChanged(FrameworkElement sender, DataC controlToAdd = colorComboBox; dependencyProperty = Selector.SelectedItemProperty; + break; + case PropertyKind.TimeSpan: + var timeSlider = new Slider(); + var timeSliderOption = option as SliderPropertyOptions; + if (timeSliderOption != null) + { + timeSlider.Minimum = timeSliderOption.MinValue; + timeSlider.Maximum = timeSliderOption.MaxValue; + timeSlider.StepFrequency = timeSliderOption.Step; + } + + if ((propertyDict[option.Name] as ValueHolder).Value is double timeValue) + { + timeSlider.Value = timeValue; + } + + controlToAdd = timeSlider; + dependencyProperty = RangeBase.ValueProperty; + converter = new TimeSpanConverter(); + break; default: var textBox = new TextBox { Text = (propertyDict[option.Name] as ValueHolder).Value.ToString() }; diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj index 1bad9dbc6b9..037de25ecb5 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj +++ b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj @@ -448,6 +448,7 @@ + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Models/PropertyDescriptor/PropertyKind.cs b/Microsoft.Toolkit.Uwp.SampleApp/Models/PropertyDescriptor/PropertyKind.cs index 1a9be270753..89a4ac41cf2 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Models/PropertyDescriptor/PropertyKind.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/Models/PropertyDescriptor/PropertyKind.cs @@ -19,6 +19,7 @@ public enum PropertyKind String, Enum, Bool, - Brush + Brush, + TimeSpan } } diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Models/Sample.cs b/Microsoft.Toolkit.Uwp.SampleApp/Models/Sample.cs index fd37110b2f8..4a14c3d9136 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Models/Sample.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/Models/Sample.cs @@ -406,6 +406,37 @@ public async Task PreparePropertyDescriptorAsync() continue; } + break; + case PropertyKind.TimeSpan: + try + { + var sliderOptions = new SliderPropertyOptions { DefaultValue = TimeSpan.FromMilliseconds(double.Parse(value)) }; + var parameters = match.Groups["parameters"].Value; + var split = parameters.Split('-'); + int minIndex = 0; + int minMultiplier = 1; + if (string.IsNullOrEmpty(split[0])) + { + minIndex = 1; + minMultiplier = -1; + } + + sliderOptions.MinValue = minMultiplier * double.Parse(split[minIndex]); + sliderOptions.MaxValue = double.Parse(split[minIndex + 1]); + if (split.Length > 2 + minIndex) + { + sliderOptions.Step = double.Parse(split[split.Length - 1]); + } + + options = sliderOptions; + } + catch (Exception ex) + { + Debug.WriteLine($"Unable to extract slider info from {value}({ex.Message})"); + TrackingManager.TrackException(ex); + continue; + } + break; case PropertyKind.Enum: try diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/InAppNotification/InAppNotificationXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/InAppNotification/InAppNotificationXaml.bind index 65da7d5f5e4..17e3445d18e 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/InAppNotification/InAppNotificationXaml.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/InAppNotification/InAppNotificationXaml.bind @@ -283,7 +283,7 @@ diff --git a/Microsoft.Toolkit.Uwp.SampleApp/readme.md b/Microsoft.Toolkit.Uwp.SampleApp/readme.md index 44e31fdf8d8..b8c842491ae 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/readme.md +++ b/Microsoft.Toolkit.Uwp.SampleApp/readme.md @@ -38,6 +38,7 @@ You can define "interactive" values in this file. The value types can be: * String: You want the user to provide a text. The string is built like this @[Name:**String**:Default value] * Slider: You want the user to provide a double value. The string is built like this @[Name:**Slider**:Default value:min-max] * DoubleSlider: Same as slider but with double values (0.01 precision) +* TimeSpan: You want the user to a duration. The string is built like this (all values in miliseconds) @[Name:**TimeSpan**:DefaultValue:min-max] * Enum: You want the user to provide a enum value. The string is built like this @[Name:**Enum**:EnumType.DefaultValue] * Brush: You want the user to select a color from a list. The string is built like this @[Name:**Brush**:Black] * Bool: You want the user to enable or disable a property. The string is built like this @[Name:**Bool**:True] diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.AttachedProperties.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.AttachedProperties.cs new file mode 100644 index 00000000000..11e6195f095 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.AttachedProperties.cs @@ -0,0 +1,54 @@ +using System; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Media.Animation; + +namespace Microsoft.Toolkit.Uwp.UI.Controls +{ + /// + /// In App Notification defines a control to show local notification in the app. + /// + public partial class InAppNotification + { + /// + /// Gets the value of the KeyFrameDuration attached Property + /// + /// the KeyFrame where the duration is set + /// Value of KeyFrameDuration + public static TimeSpan GetKeyFrameDuration(DependencyObject obj) + { + return (TimeSpan)obj.GetValue(KeyFrameDurationProperty); + } + + /// + /// Sets the value of the KeyFrameDuration attached property + /// + /// The KeyFrame object where the property is attached + /// The TimeSpan value to be set as duration + public static void SetKeyFrameDuration(DependencyObject obj, TimeSpan value) + { + obj.SetValue(KeyFrameDurationProperty, value); + } + + /// + /// Using a DependencyProperty as the backing store for KeyFrameDuration. This enables animation, styling, binding, etc + /// + public static readonly DependencyProperty KeyFrameDurationProperty = + DependencyProperty.RegisterAttached("KeyFrameDuration", typeof(TimeSpan), typeof(InAppNotification), new PropertyMetadata(0, OnKeyFrameAnimationChanged)); + + private static void OnKeyFrameAnimationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (e.NewValue is TimeSpan ts) + { + var keyTimeFromAnimationDuration = KeyTime.FromTimeSpan(ts); + if (d is DoubleKeyFrame dkf) + { + dkf.KeyTime = KeyTime.FromTimeSpan(ts); + } + else if (d is ObjectKeyFrame okf) + { + okf.KeyTime = KeyTime.FromTimeSpan(ts); + } + } + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Properties.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Properties.cs index a4c557dbae7..933dff60c99 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Properties.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Properties.cs @@ -10,6 +10,7 @@ // THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE. // ****************************************************************** +using System; using Windows.UI.Xaml; namespace Microsoft.Toolkit.Uwp.UI.Controls @@ -29,19 +30,19 @@ public partial class InAppNotification /// Identifies the dependency property. /// public static readonly DependencyProperty AnimationDurationProperty = - DependencyProperty.Register(nameof(AnimationDuration), typeof(int), typeof(InAppNotification), new PropertyMetadata(100, OnAnimationDurationChanged)); + DependencyProperty.Register(nameof(AnimationDuration), typeof(TimeSpan), typeof(InAppNotification), new PropertyMetadata(TimeSpan.FromMilliseconds(100))); /// /// Identifies the dependency property. /// public static readonly DependencyProperty VerticalOffsetProperty = - DependencyProperty.Register(nameof(VerticalOffset), typeof(double), typeof(InAppNotification), new PropertyMetadata(100, OnVerticalOffsetChanged)); + DependencyProperty.Register(nameof(VerticalOffset), typeof(double), typeof(InAppNotification), new PropertyMetadata(100)); /// /// Identifies the dependency property. /// public static readonly DependencyProperty HorizontalOffsetProperty = - DependencyProperty.Register(nameof(HorizontalOffset), typeof(double), typeof(InAppNotification), new PropertyMetadata(0, OnHorizontalOffsetChanged)); + DependencyProperty.Register(nameof(HorizontalOffset), typeof(double), typeof(InAppNotification), new PropertyMetadata(0)); /// /// Gets or sets a value indicating whether to show the Dismiss button of the control. @@ -55,9 +56,9 @@ public bool ShowDismissButton /// /// Gets or sets a value indicating the duration of the popup animation (in milliseconds). /// - public int AnimationDuration + public TimeSpan AnimationDuration { - get { return (int)GetValue(AnimationDurationProperty); } + get { return (TimeSpan)GetValue(AnimationDurationProperty); } set { SetValue(AnimationDurationProperty, value); } } @@ -89,29 +90,5 @@ private static void OnShowDismissButtonChanged(DependencyObject d, DependencyPro inApNotification._dismissButton.Visibility = showDismissButton ? Visibility.Visible : Visibility.Collapsed; } } - - private static void OnAnimationDurationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - var inApNotification = d as InAppNotification; - - int duration = (int)e.NewValue; - inApNotification.UpdateAnimationDuration(duration); - } - - private static void OnVerticalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - var inApNotification = d as InAppNotification; - - double verticalOffset = (double)e.NewValue; - inApNotification.UpdateVerticalOffset(verticalOffset); - } - - private static void OnHorizontalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - var inApNotification = d as InAppNotification; - - double horizontalOffset = (double)e.NewValue; - inApNotification.UpdateHorizontalOffset(horizontalOffset); - } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs index 5ea17c485a5..60ac3914ddd 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs @@ -57,13 +57,6 @@ protected override void OnApplyTemplate() _dismissButton.Click += DismissButton_Click; } - if (_visualStateGroup != null) - { - UpdateAnimationDuration(AnimationDuration); - UpdateVerticalOffset(VerticalOffset); - UpdateHorizontalOffset(HorizontalOffset); - } - if (Visibility == Visibility.Visible) { VisualStateManager.GoToState(this, StateContentVisible, true); @@ -96,7 +89,7 @@ public void Show(int duration = 0) Visibility = Visibility.Visible; VisualStateManager.GoToState(this, StateContentVisible, true); - _animationTimer.Interval = TimeSpan.FromMilliseconds(AnimationDuration); + _animationTimer.Interval = AnimationDuration; _animationTimer.Tick += OpenAnimationTimer_Tick; _animationTimer.Start(); @@ -174,112 +167,10 @@ private void Dismiss(InAppNotificationDismissKind dismissKind) VisualStateManager.GoToState(this, StateContentCollapsed, true); - _animationTimer.Interval = TimeSpan.FromMilliseconds(AnimationDuration); + _animationTimer.Interval = AnimationDuration; _animationTimer.Tick += DismissAnimationTimer_Tick; _animationTimer.Start(); } } - - private void UpdateAnimationDuration(int duration) - { - if (_visualStateGroup != null) - { - var keyTimeFromAnimationDuration = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(duration)); - - foreach (var state in _visualStateGroup.States) - { - foreach (var timeline in state.Storyboard.Children) - { - if (timeline is DoubleAnimationUsingKeyFrames daukf) - { - var keyFramesCount = daukf.KeyFrames.Count; - if (keyFramesCount > 1) - { - daukf.KeyFrames[keyFramesCount - 1].KeyTime = keyTimeFromAnimationDuration; - } - } - - if (timeline is ObjectAnimationUsingKeyFrames oaukf) - { - var keyFramesCount = oaukf.KeyFrames.Count; - if (keyFramesCount > 1) - { - oaukf.KeyFrames[keyFramesCount - 1].KeyTime = keyTimeFromAnimationDuration; - } - } - } - } - } - } - - private void UpdateVerticalOffset(double verticalOffset) - { - if (_visualStateGroup != null) - { - foreach (var state in _visualStateGroup.States) - { - foreach (var timeline in state.Storyboard.Children) - { - if (timeline is DoubleAnimationUsingKeyFrames daukf) - { - var targetProperty = (string)timeline.GetValue(Storyboard.TargetPropertyProperty); - - if (targetProperty == "(UIElement.RenderTransform).(CompositeTransform.TranslateY)") - { - var keyFramesCount = daukf.KeyFrames.Count; - - if (keyFramesCount > 1) - { - if (state.Name == "Visible") - { - daukf.KeyFrames[0].Value = verticalOffset; - } - - if (state.Name == "Collapsed") - { - daukf.KeyFrames[keyFramesCount - 1].Value = verticalOffset; - } - } - } - } - } - } - } - } - - private void UpdateHorizontalOffset(double horizontalOffset) - { - if (_visualStateGroup != null) - { - foreach (var state in _visualStateGroup.States) - { - foreach (var timeline in state.Storyboard.Children) - { - if (timeline is DoubleAnimationUsingKeyFrames daukf) - { - var targetProperty = (string)timeline.GetValue(Storyboard.TargetPropertyProperty); - - if (targetProperty == "(UIElement.RenderTransform).(CompositeTransform.TranslateX)") - { - var keyFramesCount = daukf.KeyFrames.Count; - - if (keyFramesCount > 1) - { - if (state.Name == "Visible") - { - daukf.KeyFrames[0].Value = horizontalOffset; - } - - if (state.Name == "Collapsed") - { - daukf.KeyFrames[keyFramesCount - 1].Value = horizontalOffset; - } - } - } - } - } - } - } - } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/Styles/MSEdgeNotificationStyle.xaml b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/Styles/MSEdgeNotificationStyle.xaml index 8088252e3f0..300f891d2b5 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/Styles/MSEdgeNotificationStyle.xaml +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/Styles/MSEdgeNotificationStyle.xaml @@ -77,13 +77,15 @@ - + - + Visible - + Collapsed @@ -106,14 +108,14 @@ - - + + - - + + From 1178f6bada7f52bed0c6c0f04dc71e4888f14e56 Mon Sep 17 00:00:00 2001 From: Odonno Date: Sat, 4 Nov 2017 12:30:22 +0100 Subject: [PATCH 15/21] docs(InAppNotification): update code blocks --- docs/controls/InAppNotification.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/controls/InAppNotification.md b/docs/controls/InAppNotification.md index 6f5389168ca..a6c05f2325e 100644 --- a/docs/controls/InAppNotification.md +++ b/docs/controls/InAppNotification.md @@ -29,19 +29,19 @@ You have multiple options to show an in-app notification. 1. By simply displaying the notification using the current template -```c# +```csharp ExampleInAppNotification.Show(); ``` 2. By using a simple text content. -```c# +```csharp ExampleInAppNotification.Show("Some text."); ``` 3. By using a UIElement (with a container as parent, ex: Grid) -```c# +```csharp var grid = new Grid(); // TODO : Construct the Grid in C# @@ -51,7 +51,7 @@ ExampleInAppNotification.Show(grid); 4. By using a DataTemplate -```c# +```csharp object inAppNotificationWithButtonsTemplate; bool isTemplatePresent = Resources.TryGetValue("InAppNotificationWithButtonsTemplate", out inAppNotificationWithButtonsTemplate); @@ -65,13 +65,13 @@ if (isTemplatePresent && inAppNotificationWithButtonsTemplate is DataTemplate) By passing a second argument to the `Show()` method, you can set the duration of the notification (in milliseconds). -```c# +```csharp ExampleInAppNotification.Show("Some text.", 2000); // the notification will appear for 2 seconds ``` ### Dismiss notification -```c# +```csharp ExampleInAppNotification.Dismiss(); ``` @@ -92,7 +92,7 @@ To hide it, simply set the property to `ShowDismissButton="False"`. This event is raised just before the notification starts to open. -```c# +```csharp private void InAppNotification_OnOpening(object sender, InAppNotificationOpeningEventArgs e) { // TODO @@ -103,7 +103,7 @@ private void InAppNotification_OnOpening(object sender, InAppNotificationOpening This event is raised when the notification is fully opened (after open animation). -```c# +```csharp private void InAppNotification_OnOpened(object sender, EventArgs e) { // TODO @@ -114,7 +114,7 @@ private void InAppNotification_OnOpened(object sender, EventArgs e) This event is raised when the system or your user started to close the notification. -```c# +```csharp private void InAppNotification_OnClosing(object sender, InAppNotificationDismissingEventArgs e) { // TODO @@ -133,7 +133,7 @@ private void InAppNotification_OnClosing(object sender, InAppNotificationDismiss This event is raised when the notification is fully closed (after close animation). -```c# +```csharp private void InAppNotification_OnClosed(object sender, EventArgs e) { // TODO @@ -179,7 +179,7 @@ If you want to use another style than the default one, please follow the example 2. Apply the `Style` -```xml +```xaml From f5e38ef6ca7c760b012bbe569bfabc38f7d05808 Mon Sep 17 00:00:00 2001 From: Odonno Date: Sat, 4 Nov 2017 12:35:38 +0100 Subject: [PATCH 16/21] docs(InAppNotification): change type of AnimationDuration property --- docs/controls/InAppNotification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/controls/InAppNotification.md b/docs/controls/InAppNotification.md index a6c05f2325e..18d17a16eda 100644 --- a/docs/controls/InAppNotification.md +++ b/docs/controls/InAppNotification.md @@ -147,7 +147,7 @@ You can update the animation using three distinct properties : | Animation properties | Type | Description | | -- | -- | -- | -| `AnimationDuration` | int | Duration of the popup animation in milliseconds | +| `AnimationDuration` | TimeSpan | Duration of the popup animation in milliseconds | | `VerticalOffset` | double | Vertical offset of the popup animation | | `HorizontalOffset` | double | Horizontal offset of the popup animation | From fb5282fe85a70edfe0efb7900dc854616b8cda45 Mon Sep 17 00:00:00 2001 From: Odonno Date: Sun, 5 Nov 2017 12:49:59 +0100 Subject: [PATCH 17/21] docs(InAppNotification): use Note block --- docs/controls/InAppNotification.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/controls/InAppNotification.md b/docs/controls/InAppNotification.md index 18d17a16eda..d5a59a81c49 100644 --- a/docs/controls/InAppNotification.md +++ b/docs/controls/InAppNotification.md @@ -21,7 +21,8 @@ The control should be placed where you want your notification to be displayed in ``` -**Note:** Since the control is part of the page visual tree, it will render in the order it was added in the parent control, and might be hidden by other elements. For the control to render on top of other elements, add it as the last child of the parent control or set the Canvas.ZIndex to a high number. +> [!NOTE] +Since the control is part of the page visual tree, it will render in the order it was added in the parent control, and might be hidden by other elements. For the control to render on top of other elements, add it as the last child of the parent control or set the Canvas.ZIndex to a high number. ### Show notification From 2093c1ae2baba9c945fa33173557b1ef3ae8231f Mon Sep 17 00:00:00 2001 From: Odonno Date: Tue, 7 Nov 2017 21:37:18 +0100 Subject: [PATCH 18/21] docs(SampleApp): fix docs on TimeSpan --- Microsoft.Toolkit.Uwp.SampleApp/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/readme.md b/Microsoft.Toolkit.Uwp.SampleApp/readme.md index 82118ab8255..dc7d1600d02 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/readme.md +++ b/Microsoft.Toolkit.Uwp.SampleApp/readme.md @@ -38,7 +38,7 @@ You can define "interactive" values in this file. The value types can be: * String: You want the user to provide a text. The string is built like this @[Name:**String**:Default value] * Slider: You want the user to provide a double value. The string is built like this @[Name:**Slider**:Default value:min-max] * DoubleSlider: Same as slider but with double values (0.01 precision) -* TimeSpan: You want the user to a duration. The string is built like this (all values in miliseconds) @[Name:**TimeSpan**:DefaultValue:min-max] +* TimeSpan: You want the user to provide a duration. The string is built like this (all values in miliseconds) @[Name:**TimeSpan**:DefaultValue:min-max] * Enum: You want the user to provide a enum value. The string is built like this @[Name:**Enum**:EnumType.DefaultValue] * Brush: You want the user to select a color from a list. The string is built like this @[Name:**Brush**:Black] * Bool: You want the user to enable or disable a property. The string is built like this @[Name:**Bool**:True] From b8c5e5f4ea978e8857f09599a616dc252d936af9 Mon Sep 17 00:00:00 2001 From: Odonno Date: Tue, 7 Nov 2017 21:41:21 +0100 Subject: [PATCH 19/21] refactor(InAppNotification): remove Dismissing event --- .../InAppNotification.Events.cs | 6 --- .../InAppNotification/InAppNotification.cs | 5 +- .../InAppNotificationDismissingEventArgs.cs | 48 ------------------- 3 files changed, 1 insertion(+), 58 deletions(-) delete mode 100644 Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationDismissingEventArgs.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Events.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Events.cs index 714dc9d0811..21038c175f9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Events.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Events.cs @@ -31,12 +31,6 @@ public partial class InAppNotification /// public event EventHandler Opened; - /// - /// Event raised when the notification is dismissing - /// - [Obsolete("Use Closing event instead.")] - public event InAppNotificationDismissingEventHandler Dismissing; - /// /// Event raised when the notification is dismissed /// diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs index 60ac3914ddd..6a7a7049178 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs @@ -154,13 +154,10 @@ private void Dismiss(InAppNotificationDismissKind dismissKind) { _animationTimer.Stop(); - var dismissingEventArgs = new InAppNotificationDismissingEventArgs(dismissKind); - Dismissing?.Invoke(this, dismissingEventArgs); - var closingEventArgs = new InAppNotificationClosingEventArgs(dismissKind); Closing?.Invoke(this, closingEventArgs); - if (dismissingEventArgs.Cancel || closingEventArgs.Cancel) + if (closingEventArgs.Cancel) { return; } diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationDismissingEventArgs.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationDismissingEventArgs.cs deleted file mode 100644 index b2c0e35564f..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationDismissingEventArgs.cs +++ /dev/null @@ -1,48 +0,0 @@ -// ****************************************************************** -// Copyright (c) Microsoft. All rights reserved. -// This code is licensed under the MIT License (MIT). -// THE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH -// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE. -// ****************************************************************** - -using System; - -namespace Microsoft.Toolkit.Uwp.UI.Controls -{ - /// - /// A delegate for dismissing. - /// - /// The sender. - /// The event arguments. - public delegate void InAppNotificationDismissingEventHandler(object sender, InAppNotificationDismissingEventArgs e); - - /// - /// Provides data for the Dismissing event. - /// - public class InAppNotificationDismissingEventArgs : EventArgs - { - /// - /// Initializes a new instance of the class. - /// - /// Dismiss kind that triggered the dismissing event - public InAppNotificationDismissingEventArgs(InAppNotificationDismissKind dismissKind) - { - DismissKind = dismissKind; - } - - /// - /// Gets the kind of action for the dismissing event. - /// - public InAppNotificationDismissKind DismissKind { get; private set; } - - /// - /// Gets or sets a value indicating whether the notification should be dismissed. - /// - public bool Cancel { get; set; } - } -} From 33a1c3e27ba821e5ff7ca4e5a1dfb8bf3da2a3ab Mon Sep 17 00:00:00 2001 From: Odonno Date: Tue, 7 Nov 2017 22:04:54 +0100 Subject: [PATCH 20/21] docs(InAppNotification): add missing header --- .../InAppNotification.AttachedProperties.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.AttachedProperties.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.AttachedProperties.cs index 11e6195f095..b5044912cf8 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.AttachedProperties.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.AttachedProperties.cs @@ -1,4 +1,16 @@ -using System; +// ****************************************************************** +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH +// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE. +// ****************************************************************** + +using System; using Windows.UI.Xaml; using Windows.UI.Xaml.Media.Animation; From f9ec93ac5e187a7182bdb69ff0dc0ec3c67f9eff Mon Sep 17 00:00:00 2001 From: Odonno Date: Tue, 7 Nov 2017 23:18:54 +0100 Subject: [PATCH 21/21] feat(InAppNotification): add dismiss kind info on closed event --- .../InAppNotification.Events.cs | 5 +-- .../InAppNotification/InAppNotification.cs | 3 ++ .../InAppNotificationClosedEventArgs.cs | 43 +++++++++++++++++++ 3 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationClosedEventArgs.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Events.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Events.cs index 21038c175f9..6c4550ff2a8 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Events.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.Events.cs @@ -11,7 +11,6 @@ // ****************************************************************** using System; -using Windows.Foundation.Metadata; using Windows.UI.Xaml; namespace Microsoft.Toolkit.Uwp.UI.Controls @@ -45,7 +44,7 @@ public partial class InAppNotification /// /// Event raised when the notification is closed /// - public event EventHandler Closed; + public event InAppNotificationClosedEventHandler Closed; private void DismissButton_Click(object sender, RoutedEventArgs e) { @@ -69,7 +68,7 @@ private void DismissAnimationTimer_Tick(object sender, object e) { _animationTimer.Stop(); Dismissed?.Invoke(this, EventArgs.Empty); - Closed?.Invoke(this, EventArgs.Empty); + Closed?.Invoke(this, new InAppNotificationClosedEventArgs(_lastDismissKind)); _animationTimer.Tick -= DismissAnimationTimer_Tick; } } diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs index 6a7a7049178..8ceb8d8a3e3 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotification.cs @@ -25,6 +25,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls [TemplatePart(Name = DismissButtonPart, Type = typeof(Button))] public sealed partial class InAppNotification : ContentControl { + private InAppNotificationDismissKind _lastDismissKind; private DispatcherTimer _animationTimer = new DispatcherTimer(); private DispatcherTimer _dismissTimer = new DispatcherTimer(); private Button _dismissButton; @@ -164,6 +165,8 @@ private void Dismiss(InAppNotificationDismissKind dismissKind) VisualStateManager.GoToState(this, StateContentCollapsed, true); + _lastDismissKind = dismissKind; + _animationTimer.Interval = AnimationDuration; _animationTimer.Tick += DismissAnimationTimer_Tick; _animationTimer.Start(); diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationClosedEventArgs.cs b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationClosedEventArgs.cs new file mode 100644 index 00000000000..87ccf2aa12c --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Controls/InAppNotification/InAppNotificationClosedEventArgs.cs @@ -0,0 +1,43 @@ +// ****************************************************************** +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH +// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE. +// ****************************************************************** + +using System; + +namespace Microsoft.Toolkit.Uwp.UI.Controls +{ + /// + /// A delegate for dismissing. + /// + /// The sender. + /// The event arguments. + public delegate void InAppNotificationClosedEventHandler(object sender, InAppNotificationClosedEventArgs e); + + /// + /// Provides data for the Dismissing event. + /// + public class InAppNotificationClosedEventArgs : EventArgs + { + /// + /// Initializes a new instance of the class. + /// + /// Dismiss kind that triggered the closing event + public InAppNotificationClosedEventArgs(InAppNotificationDismissKind dismissKind) + { + DismissKind = dismissKind; + } + + /// + /// Gets the kind of action for the closing event. + /// + public InAppNotificationDismissKind DismissKind { get; private set; } + } +}