WinUI 3.0 (Project Reunion 0.5) で ContentDialog を使う方法

2021/04/04に公開

Project Reunion こと Windows UI Library 3.0 を試していたら ContentDialog を使ってダイアログを表示するのに、少しはまったのでメモ。

ContentDialog を Win32 (.NET 5) 上の Win UI 3.0 で使うには XamlRoot プロパティの設定が必須っぽいです。(少なくとも Project Reunion 0.5 の時点では)

なので、Window のボタンクリックイベントでダイアログを表示する場合のコードは以下のようになります。

MainWindow.xaml.cs
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System;

namespace App3
{
    public sealed partial class MainWindow : Window
    {
        public MainWindow()
        {
            this.InitializeComponent();
        }

        private async void MyButton_Click(object sender, RoutedEventArgs e)
        {
            var dlg = new ContentDialog
            {
                Title = "Info",
                Content = "こんにちは!",
                PrimaryButtonText = "Close",
                // ここの設定が必須!!
                XamlRoot = this.Content.XamlRoot,
            };
            await dlg.ShowAsync();
        }

    }
}

本題とは関係ありませんが XAML 側も一応のせておきます。

MainWindow.xaml
<Window
    x:Class="App3.MainWindow"
    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:local="using:App3"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
        <Button Click="MyButton_Click" Content="Click me" />
    </StackPanel>
</Window>

実行してボタンを押すと、以下のように表示されます。イイ感じ。

XamlRoot を設定しない場合…

以下のようなわかりにくいエラーが出ます。

Exception thrown at 0x76C7A8B2 (KernelBase.dll) in App3.exe: WinRT originate error - 0x80070057 : 'This element is already associated with a XamlRoot, it cannot be associated with a different one until it is removed from the previous XamlRoot.'.
Exception thrown: 'System.ArgumentException' in WinRT.Runtime.dll
WinRT information: This element is already associated with a XamlRoot, it cannot be associated with a different one until it is removed from the previous XamlRoot.
An exception of type 'System.ArgumentException' occurred in WinRT.Runtime.dll but was not handled in user code
WinRT information: This element is already associated with a XamlRoot, it cannot be associated with a different one until it is removed from the previous XamlRoot.
Value does not fall within the expected range.
Microsoft (有志)

Discussion