Skip to content

Fixed stack corruption bug in InAppNotification in sample #3802

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
10 commits merged into from
Mar 4, 2021

Conversation

shweaver-MSFT
Copy link
Member

Fixes #3391

In the InAppNotifications sample page, there is the option to display a notification with or without a custom DataTemplate. Mixing the usage of these buttons in the sample app with a StackMode other than "Replace", would cause cause the notifications to show double close buttons, or be out of alignment.

PR Type

What kind of change does this PR introduce?

  • Bugfix

What is the current behavior?

Currently, the sample page for InAppNotifications shows the bug when interacting with the "... (with/without DataTemplate)" buttons. This is due to some odd wiring in the code behind. Though 3 notification objects were defined in XAML, only two were actually used. The third is configured to show the custom data template; But when it was time to show another notification it hot swaps templates with the custom notification, and attempts to show the custom content. Unfortunately this causes a bunch of issues because the need to display the close button and what content to show gets out of sync when we start to close the stack of notifications.

What is the new behavior?

In the update sample page, I've started using the third notification object. It maintains a separate stack because it is a separate notification, but so does the VS styled notification. The advise to developers going forward is to pick a model, not mix and match. Hot-swapping templates is not supported.

To support the flow of the sample, I added an option to pass an argument to the Dismiss function.

InAppNotification.Dismiss(bool dismissAll = false)

Passing true will dismiss all of the notifications in the stack. I read that there was a comment in the sample code-behind saying, "Do not dismiss all in production", but I disagree. Sometimes you really need to dismiss them all, such as during major app navigations (sign in/out). If a whole stack of notifications becomes suddenly irrelevant we should be able to dismiss them all. It's useful in the sample as well, for when we switch between the three notifications.

Lastly, in this process I uncovered a bug that causes the notification not to render when reusing the same DataTemplate. Here is the snippet from InAppNotification.cs

// From InAppNotifcation.UpdateContent(NotificationOptions notificationOptions)

    case DataTemplate dataTemplate:
        // 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;

PR Checklist

Please check if your PR fulfills the following requirements:

  • Tested code with current supported SDKs
  • Pull Request has been submitted to the documentation repository instructions. Link:
  • Sample in sample app has been added / updated (for bug fixes / features)
  • New major technical changes in the toolkit have or will be added to the Wiki e.g. build changes, source generators, testing infrastructure, sample creation changes, etc...
  • Tests for the changes have been added (for bug fixes / features) (if applicable)
  • Header has been added to all new source files (run build/UpdateHeaders.bat)
  • Contains NO breaking changes

Other information

Todo:

  • Document the new dismissAll flag.

@ghost
Copy link

ghost commented Mar 2, 2021

Thanks shweaver-MSFT for opening a Pull Request! The reviewers will test the PR and highlight if there is any conflict or changes required. If the PR is approved we will proceed to merge the pull request 🙌

@ghost ghost requested review from michael-hawker, azchohfi, Kyaa-dost and Rosuavio March 2, 2021 21:00
@ghost ghost added bug 🐛 An unexpected issue that highlights incorrect behavior controls 🎛️ labels Mar 2, 2021
@Kyaa-dost Kyaa-dost added this to the 7.0 milestone Mar 2, 2021
Copy link
Contributor

@Kyaa-dost Kyaa-dost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix @shweaver-MSFT! Looks great 🚀

@ghost
Copy link

ghost commented Mar 2, 2021

Hello @Kyaa-dost!

Because this pull request has the auto merge :zap: label, I will be glad to assist with helping to merge this pull request once all check-in policies pass.

Do note that I've been instructed to only help merge pull requests of this repository that have been opened for at least 8 hours, a condition that will be fulfilled in about 6 hours 43 minutes. No worries though, I will be back when the time is right! 😉

p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (@msftbot) and give me an instruction to get started! Learn more here.

@Kyaa-dost
Copy link
Contributor

@msftbot merge this PR once approved by @michael-hawker

@ghost
Copy link

ghost commented Mar 2, 2021

Hello @Kyaa-dost!

Because you've given me some instructions on how to help merge this pull request, I'll be modifying my merge approach. Here's how I understand your requirements for merging this pull request:

If this doesn't seem right to you, you can tell me to cancel these instructions and use the auto-merge policy that has been configured for this repository. Try telling me "forget everything I just told you".

Opening?.Invoke(this, eventArgs);

if (eventArgs.Cancel)
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this causing an issue somewhere else? Didn't see this called out in the PR notes.

In either case it needs to be DispatcherQueue now. 🙂 Dispatcher is no longer a thing we should use. We have the DispatcherQueue helpers we use in other controls too, but if InAppNotification doesn't have a reference already, this may get a bit messy.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Crap just noticed we have DispatcherTimer at the top too, it should probably be DispatcherQueueTimer... I'm assuming @azchohfi made these updates in the WinUI 3 branch, I'll check quick.

Copy link
Member

@michael-hawker michael-hawker Mar 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, I'm seeing a lot of Dispatchers still in the code, thought we had fixed them all early on. I'll file an issue to track these later. Think ThemeListener is the best pattern we have currently, but not sure if we've tried that pattern on a Control yet.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me try removing them and see how it goes. I tend to add them during debugging to see if the XAML timer is causing any issues. They may not be necessary at all tbh

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha! I've made the fixes for InAppNotification. Works well :) Thanks for the hint on ThemeListener, it was a good example.

Copy link
Member

@michael-hawker michael-hawker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks @shweaver-MSFT! 🎉🎉🎉

@@ -34,7 +36,11 @@ public InAppNotification()
{
DefaultStyleKey = typeof(InAppNotification);

_dispatcherQueue = DispatcherQueue.GetForCurrentThread();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call, I suppose with a UI control (compared to something like ThemeListener) there'd be no reason to use a DispatcherQueue other than the one we get initially on the UI Thread here (as the UI Thread should hopefully be the one initializing the control...).

Right @azchohfi?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I figured. Plus, XAML objects don't like non-empty constructors, and even declaring the default as null is not enough to appease the compiler. This made most sense to me :)

@michael-hawker
Copy link
Member

@Kyaa-dost this one can be merged once #3796 is merged.

@Kyaa-dost
Copy link
Contributor

@msftbot nevermind

@ghost
Copy link

ghost commented Mar 3, 2021

Hello @Kyaa-dost!

Because you've told me to reset the custom auto-merge settings, I'll use the configured settings for this repository when I'm merging this pull request.

@CommunityToolkit CommunityToolkit deleted a comment Mar 3, 2021
@CommunityToolkit CommunityToolkit deleted a comment Mar 3, 2021
@CommunityToolkit CommunityToolkit deleted a comment Mar 3, 2021
@Kyaa-dost
Copy link
Contributor

@msftbot hold this for 1 hour

@ghost
Copy link

ghost commented Mar 3, 2021

Hello @Kyaa-dost!

Because you've given me some instructions on how to help merge this pull request, I'll be modifying my merge approach. Here's how I understand your requirements for merging this pull request:

  • I won't merge this pull request until after the UTC date Thu, 04 Mar 2021 00:48:28 GMT, which is in 1 hour

If this doesn't seem right to you, you can tell me to cancel these instructions and use the auto-merge policy that has been configured for this repository. Try telling me "forget everything I just told you".

@Kyaa-dost
Copy link
Contributor

@msftbot merge this PR

@ghost
Copy link

ghost commented Mar 4, 2021

Hello @Kyaa-dost!

I think you told me that you want to delay the approval for a certain amount of time, but I am not confident that I have understood you correctly.

Please try rephrasing your instruction to me.

@Kyaa-dost
Copy link
Contributor

@msftbot nevermind

@ghost
Copy link

ghost commented Mar 4, 2021

Hello @Kyaa-dost!

Because you've told me to reset the custom auto-merge settings, I'll use the configured settings for this repository when I'm merging this pull request.

@ghost ghost merged commit a66da6e into master Mar 4, 2021
@ghost ghost deleted the shweaver/inappnotifications branch March 4, 2021 01:24
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auto merge ⚡ bug 🐛 An unexpected issue that highlights incorrect behavior controls 🎛️ sample app 🖼
Projects
None yet
Development

Successfully merging this pull request may close these issues.

InAppNotification Display gets corrupted when pushing messages with different methods in queue/stack
3 participants