diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/InAppNotification/InAppNotificationPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/InAppNotification/InAppNotificationPage.xaml.cs index 7009a18297c..c962a517cb2 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/InAppNotification/InAppNotificationPage.xaml.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/InAppNotification/InAppNotificationPage.xaml.cs @@ -14,8 +14,6 @@ namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages { public sealed partial class InAppNotificationPage : Page, IXamlRenderListener { - private ControlTemplate _defaultInAppNotificationControlTemplate; - private ControlTemplate _customInAppNotificationControlTemplate; private InAppNotification _exampleInAppNotification; private InAppNotification _exampleCustomInAppNotification; private InAppNotification _exampleVSCodeInAppNotification; @@ -36,9 +34,7 @@ public void OnXamlRendered(FrameworkElement control) NotificationDuration = 0; _exampleInAppNotification = control.FindChild("ExampleInAppNotification") as InAppNotification; - _defaultInAppNotificationControlTemplate = _exampleInAppNotification?.Template; _exampleCustomInAppNotification = control.FindChild("ExampleCustomInAppNotification") as InAppNotification; - _customInAppNotificationControlTemplate = _exampleCustomInAppNotification?.Template; _exampleVSCodeInAppNotification = control.FindChild("ExampleVSCodeInAppNotification") as InAppNotification; _resources = control.Resources; @@ -53,15 +49,15 @@ private void Load() { SampleController.Current.RegisterNewCommand("Show notification with random text", (sender, args) => { - _exampleVSCodeInAppNotification?.Dismiss(); - SetDefaultControlTemplate(); + _exampleVSCodeInAppNotification.Dismiss(true); + _exampleCustomInAppNotification.Dismiss(true); _exampleInAppNotification?.Show(GetRandomText(), NotificationDuration); }); SampleController.Current.RegisterNewCommand("Show notification with object", (sender, args) => { - _exampleVSCodeInAppNotification?.Dismiss(); - SetDefaultControlTemplate(); + _exampleVSCodeInAppNotification.Dismiss(true); + _exampleCustomInAppNotification.Dismiss(true); var random = new Random(); _exampleInAppNotification?.Show(new KeyValuePair(random.Next(1, 10), GetRandomText()), NotificationDuration); @@ -69,8 +65,8 @@ private void Load() SampleController.Current.RegisterNewCommand("Show notification with buttons (without DataTemplate)", (sender, args) => { - _exampleVSCodeInAppNotification?.Dismiss(); - SetDefaultControlTemplate(); + _exampleVSCodeInAppNotification.Dismiss(true); + _exampleCustomInAppNotification.Dismiss(true); var grid = new Grid() { @@ -126,46 +122,30 @@ private void Load() SampleController.Current.RegisterNewCommand("Show notification with buttons (with DataTemplate)", (sender, args) => { - _exampleVSCodeInAppNotification?.Dismiss(); - SetCustomControlTemplate(); // Use the custom template without the Dismiss button. The DataTemplate will handle re-adding it. + _exampleVSCodeInAppNotification.Dismiss(true); + _exampleInAppNotification.Dismiss(true); - object inAppNotificationWithButtonsTemplate = null; - bool? isTemplatePresent = _resources?.TryGetValue("InAppNotificationWithButtonsTemplate", out inAppNotificationWithButtonsTemplate); - - if (isTemplatePresent == true && inAppNotificationWithButtonsTemplate is DataTemplate template) + object inAppNotificationWithButtonsTemplateResource = null; + bool? isTemplatePresent = _resources?.TryGetValue("InAppNotificationWithButtonsTemplate", out inAppNotificationWithButtonsTemplateResource); + if (isTemplatePresent == true && inAppNotificationWithButtonsTemplateResource is DataTemplate inAppNotificationWithButtonsTemplate) { - _exampleInAppNotification.Show(template, NotificationDuration); + _exampleCustomInAppNotification.Show(inAppNotificationWithButtonsTemplate, NotificationDuration); } }); - SampleController.Current.RegisterNewCommand("Show notification with Drop Shadow (based on default template)", (sender, args) => - { - _exampleVSCodeInAppNotification.Dismiss(); - SetDefaultControlTemplate(); - - // Update control template - object inAppNotificationDropShadowControlTemplate = null; - bool? isTemplatePresent = _resources?.TryGetValue("InAppNotificationDropShadowControlTemplate", out inAppNotificationDropShadowControlTemplate); - - if (isTemplatePresent == true && inAppNotificationDropShadowControlTemplate is ControlTemplate template) - { - _exampleInAppNotification.Template = template; - } - - _exampleInAppNotification.Show(GetRandomText(), NotificationDuration); - }); - SampleController.Current.RegisterNewCommand("Show notification with Visual Studio Code template (info notification)", (sender, args) => { - _exampleInAppNotification.Dismiss(); + _exampleInAppNotification.Dismiss(true); + _exampleCustomInAppNotification.Dismiss(true); _exampleVSCodeInAppNotification.Show(NotificationDuration); }); SampleController.Current.RegisterNewCommand("Dismiss", (sender, args) => { // Dismiss all notifications (should not be replicated in production) - _exampleInAppNotification.Dismiss(); - _exampleVSCodeInAppNotification.Dismiss(); + _exampleInAppNotification.Dismiss(true); + _exampleCustomInAppNotification.Dismiss(true); + _exampleVSCodeInAppNotification.Dismiss(true); }); } @@ -182,18 +162,6 @@ private string GetRandomText() } } - private void SetDefaultControlTemplate() - { - // Update control template - _exampleInAppNotification.Template = _defaultInAppNotificationControlTemplate; - } - - private void SetCustomControlTemplate() - { - // Update control template - _exampleInAppNotification.Template = _customInAppNotificationControlTemplate; - } - private void NotificationDurationTextBox_TextChanged(object sender, TextChangedEventArgs e) { int newDuration; diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/InAppNotification/InAppNotificationXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/InAppNotification/InAppNotificationXaml.bind index 7063ec5b6f6..1783d532f86 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/InAppNotification/InAppNotificationXaml.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/InAppNotification/InAppNotificationXaml.bind @@ -18,6 +18,93 @@ + + - - - @@ -168,7 +168,7 @@ - + @@ -235,7 +235,7 @@ Height="32" Width="100" Command="{StaticResource DismissCommand}" - CommandParameter="{Binding ElementName=ExampleInAppNotification}" + CommandParameter="{Binding ElementName=ExampleCustomInAppNotification}" AutomationProperties.Name="Ok" /> - - - - - - - + - + Style="{StaticResource MSEdgeNotificationTemplate_NoDismissButton}" + ShowDismissButton="@[ShowDismissButton]" + AnimationDuration="@[AnimationDuration]" + VerticalOffset="@[VerticalOffset]" + HorizontalOffset="@[HorizontalOffset]" + StackMode="@[StackMode]" /> _stackedNotificationOptions; private VisualStateGroup _visualStateGroup; - private ContentPresenter _contentProvider; - private List _stackedNotificationOptions = new List(); /// /// Initializes a new instance of the class. @@ -34,7 +36,11 @@ public InAppNotification() { DefaultStyleKey = typeof(InAppNotification); + _dispatcherQueue = DispatcherQueue.GetForCurrentThread(); + _dismissTimer = _dispatcherQueue.CreateTimer(); _dismissTimer.Tick += DismissTimer_Tick; + + _stackedNotificationOptions = new List(); } /// @@ -160,16 +166,17 @@ public void Show(object content, int duration = 0) /// /// Dismiss the notification /// - public void Dismiss() + public void Dismiss(bool dismissAll = false) { - Dismiss(InAppNotificationDismissKind.Programmatic); + Dismiss(InAppNotificationDismissKind.Programmatic, dismissAll); } /// /// Dismiss the notification /// /// Kind of action that triggered dismiss event - private void Dismiss(InAppNotificationDismissKind dismissKind) + /// Indicates if one or all notifications should be dismissed. + private void Dismiss(InAppNotificationDismissKind dismissKind, bool dismissAll = false) { if (_stackedNotificationOptions.Count == 0) { @@ -179,8 +186,17 @@ private void Dismiss(InAppNotificationDismissKind dismissKind) _dismissTimer.Stop(); + // Dismiss all if requested + if (dismissAll) + { + _stackedNotificationOptions.Clear(); + } + else + { + _stackedNotificationOptions.RemoveAt(0); + } + // Continue to display notification if on remaining stacked notification - _stackedNotificationOptions.RemoveAt(0); if (_stackedNotificationOptions.Any()) { var notificationOptions = _stackedNotificationOptions[0]; @@ -238,8 +254,16 @@ private void UpdateContent(NotificationOptions notificationOptions) _contentProvider.Content = element; break; case DataTemplate dataTemplate: - _contentProvider.ContentTemplate = dataTemplate; - _contentProvider.Content = null; + // Without this check, the dataTemplate will fail to render. + // Why? Setting the ContentTemplate causes the control to re-evaluate it's Content value. + // When we set the ContentTemplate to the same instance of itself, we aren't actually changing the value. + // This means that the Content value won't be re-evaluated and stay null, causing the render to fail. + if (_contentProvider.ContentTemplate != dataTemplate) + { + _contentProvider.ContentTemplate = dataTemplate; + _contentProvider.Content = null; + } + break; case object content: _contentProvider.ContentTemplate = ContentTemplate;