How to create a content dialog in App.xaml.cs in WinUI3?

276 Views Asked by At

I'm making a small app with WinUI 3. The app require to connect to the Internet while loading. Then it will download some necessary resources. I can't put the network check under any one window, because all windows need the resources which have downloaded, otherwise they won't start properly. So I added a network check in the Onlaunch method in App.xaml.cs. There are the codes.

if (SystemEnvironmentHelper.IsConnectInternet() == false)
{
    //No wifi connection
    ContentDialog noWifiDialog = new ContentDialog()
    {
        Title = "No wifi connection",
        Content = "Check connection and try again.",
        CloseButtonText = "Ok"
    };

    await noWifiDialog.ShowAsync();
}

And the IsConnectInternetmethod is defined as follows.(Actually it works well)

[DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState(ref int Description, int ReservedValue);
public static bool IsConnectInternet()
{
    int Description = 0;
    return InternetGetConnectedState(ref Description, 0);
}

But when I run this app, it throw an exception System.ArgumentException. I know I should add XamlRoot, but no form is declared in App.xaml.cs, and XamlRoot does not exist. I don't know how to solve this problem because there are only a few documents and they didn't mention this problem.

Also, I'm using an unpackaged app, does Content Dialog work with unpackaged apps?

Any help are appreciated.

1

There are 1 best solutions below

0
On BEST ANSWER
  1. You should create and display a window as soon as possible after the app has been started regardless of whether you intend to display a ContentDialog. It doesn't have to be your "main" window but you should display something to confirm that your app is actually running.

  2. You cannot show a ContentDialog until there are some content displayed on the screen.

You could for example create a temporary window that shows a ProgressRing while you check the connection:

<Window
    x:Class="App1.TempWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid>
        <ProgressRing IsIndeterminate="True" />
    </Grid>
</Window>

Once the temporary window has been shown, you can then check the connection and display the dialog:

public partial class App : Application
{
    public App()
    {
        this.InitializeComponent();
    }

    protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
    {
        // 1. Show "temp" window
        m_window = new TempWindow();
        (m_window.Content as FrameworkElement).Loaded += OnLoaded;
        m_window.Activate();

    }

    private async void OnLoaded(object sender, RoutedEventArgs e)
    {
        // 2. Check connection and show dialog
        (m_window.Content as FrameworkElement).Loaded -= OnLoaded;

        //if (SystemEnvironmentHelper.IsConnectInternet() == false)
        {
            //No wifi connection
            ContentDialog noWifiDialog = new ContentDialog()
            {
                Title = "No wifi connection",
                Content = "Check connection and try again.",
                CloseButtonText = "Ok",
                XamlRoot = m_window.Content.XamlRoot
            };

            await noWifiDialog.ShowAsync();
        }

        // 3. Show main window
        var mainWindow = new MainWindow();
        mainWindow.Activate();

        // 4. Close "temp" window
        m_window.Close();
        m_window = mainWindow;
    }

    private Window m_window;
}