Search code examples
c#xamluwpwindows-10-iot-core

In UWP, how would I get the instance of a Grid, that's in a Flyout, that is itself in a ResourceDictionary?


I have a UWP app which will be deployed to a device with a screen. The device is running Windows 10 IoT Core.

I want to have some form of an alert system, and because I cannot use the UWP ToastNotification, I decided to create my own. I created a UserControl for the notification and that works fine. I show the control dynamically in a Flyout, and that works fine to a point.

Flyout is in a ResourceDictionary and looks like this:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:HCI">

    <Flyout x:Key="ToastNotificationFlyout" x:Name="ToastFlyout" 
            ShowMode="Transient" AllowFocusOnInteraction="False">
        <Grid x:Name="ToastContainer" />
    </Flyout>

</ResourceDictionary>

I have a static class...

static class Globals
{
    public static Flyout GlobalFlyout;
}

...which allows me to reference the Flyout from any class in my code (Pages loaded dynamically through a content Frame).

In my MainPage instance, I create the reference like this:

Globals.GlobalFlyout = (Flyout)Application.Current.Resources["ToastNotificationFlyout"];

I can then reference the Flyout in C#, but I cannot seem to get a reference to the Grid. Flyout doesn't contain a .FindName() method, and using VisualTreeHelper throws a Catastrophic Exception (explained in another SO issue by another user). I have also tried various invocations of .FindChild() and .FindControl(), that I've found here and in other communities, but none work for this case.

The content of the Flyout is straightforward, mimicking the look of a regular Win10 toast notification.

Any thoughts on how to reference the Grid in the Flyout, so that I can add an instance of the notification control?


Solution

  • The Grid is actually stored under the Flyout.Content property:

    var grid = (Grid)Globals.GlobalFlyout.Content;
    

    When you put a direct child inside a Flyout XAML interprets it as the Content. This is done under the hood using the ContentPropertyAttribute.