rksoftware

Visual Studio とか C# とかが好きです

WinUI3 でファイル選択ダイアログが出したい!

今日は WinUI3 でファイルを開くためのファイル選択ダイアログを出してみたいと思います。

■ WPF(.NET 6)

WPF ではこんな感じでした。

private void Button_Click(object sender, RoutedEventArgs e)
{
    var fileDialog = new Microsoft.Win32.OpenFileDialog
    {
        Multiselect = false,
    };
    if (fileDialog.ShowDialog() == true)
        MessageBox.Show(fileDialog.FileName);
    else
        MessageBox.Show("選択されませんでした");
}

ちなみに Microsoft.Win32.OpenFileDialog の在処。

C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\PresentationFramework.dll

または

C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.5\ref\net6.0\PresentationFramework.dll

■ UWP

UWP では使うものが全く変わりこんな感じです。 MessageDialog も別のものになります。

private async void Button_Click(object sender, RoutedEventArgs e)
{
    var picker = new Windows.Storage.Pickers.FileOpenPicker
    {
        ViewMode = PickerViewMode.Thumbnail,
        SuggestedStartLocation = PickerLocationId.PicturesLibrary
    };
    picker.FileTypeFilter.Add(".jpg");
    var file = await picker.PickSingleFileAsync();

    var messageDialog = new Windows.UI.Popups.MessageDialog((file == null).ToString())
    {
        DefaultCommandIndex = 0,
        CancelCommandIndex = 0,
    };
    messageDialog.Commands.Add(new Windows.UI.Popups.UICommand("OK"));
    await messageDialog.ShowAsync();
}


■ WinUI3

さて本命の WinUI3 です。

WPF のコードを WinUI3 プロジェクトのソースコードに貼り付けてみましょう。

残念ながらエラーになります。エラーの内容は OpenFileDialogMessageBox は無いというもの。

ならば今度は UWP のコードを WinUI3 プロジェクトのソースコードに。

COMException: Invalid window handle

残念ながらビルドは成功しますが実行時エラーになります。けれどもとりあえず、こういった API は WinUI3 では UWP のものということはわかります。WPF はやはりクラシックなのでしょう。

実行時エラー対策

こんな感じです。多分これはゴールでなくて今後はいらなくなると思います。

private async void Button_Click(object sender, RoutedEventArgs e)
{
    var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(this);  // 追加

    var picker = new Windows.Storage.Pickers.FileOpenPicker
    {
        ViewMode = PickerViewMode.Thumbnail,
        SuggestedStartLocation = PickerLocationId.PicturesLibrary
    };
    picker.FileTypeFilter.Add(".jpg");

    WinRT.Interop.InitializeWithWindow.Initialize(picker, hwnd);    // 追加

    var file = await picker.PickSingleFileAsync();

    var messageDialog = new Windows.UI.Popups.MessageDialog((file == null).ToString())
    {
        DefaultCommandIndex = 0,
        CancelCommandIndex = 0,
    };
    messageDialog.Commands.Add(new Windows.UI.Popups.UICommand("OK"));

    WinRT.Interop.InitializeWithWindow.Initialize(messageDialog, hwnd); // 追加

    await messageDialog.ShowAsync();
}


こうしてみるとやはり、これからは WinUI という感じがしてきますね。備えましょう。

参考

github.com