0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【WPF】ファイル選択ダイアログを表示する方法【MVVM】

Posted at

ダイアログを表示したい

WPFアプリを作成しているときにダイアログを表示したい状況って多いと思います。
MVVMパターンを採用しているときにダイアログを表示する場合ってどうしたらいいのか、検索してもいろいろな方法が出てきてどれがいいんだろうとなりますよね。
今回、自分なりにしっくりきた実装を紹介したいと思います。

使用したライブラリ

  • CommunityToolkit.Mvvm

実装

MainWindow.xaml
<Window x:Class="OpenFileDialogSample.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:OpenFileDialogSample"
        xmlns:vm="clr-namespace:OpenFileDialogSample"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <vm:MainWindowViewModel/>
    </Window.DataContext>
    <Grid>
        <StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Center" Margin="16">
            <Button Content="ファイル選択" Command="{Binding FileSelectCommand}" 
            Width="100" Margin="8"/>
            <TextBox Text="{Binding SelectedFilePath}" Margin="8"/>
        </StackPanel>
    </Grid>
</Window>
MainWindow.xaml.cs
using System.Windows;
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.Win32;

namespace OpenFileDialogSample
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            WeakReferenceMessenger.Default.Register<MainWindow, FileSelectRequest>
            (this, static (s, e) =>
            {
                OpenFileDialog ofd = new OpenFileDialog();
                ofd.FileName = e.OldSelectFilePath;
                if(ofd.ShowDialog() == true)
                {
                    e.Reply(ofd.FileName);
                }
                else
                {
                    e.Reply(string.Empty);
                }
            });
        }
    }
}
MainWindowViewModel.cs
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using System.IO;

namespace OpenFileDialogSample
{
    internal partial class MainWindowViewModel : ObservableObject
    {
        [ObservableProperty]
        private string selectedFilePath;

        [RelayCommand]
        private void FileSelect()
        {
            var reply = WeakReferenceMessenger.Default.Send(new FileSelectRequest()
            {
                OldSelectFilePath = SelectedFilePath
            });
            if(File.Exists(reply.Response))
            {
                SelectedFilePath = reply.Response;
            }
        }
    }
}
Message.cs
using CommunityToolkit.Mvvm.Messaging.Messages;

namespace OpenFileDialogSample
{
    internal class FileSelectRequest : RequestMessage<string>
    {
        public FileSelectRequest() { }
        public string OldSelectFilePath;
    }
}

WeakReferenceMessengerが便利

昔はMessengerパターンって難しくてわからないってなってたんですが、CommunityToolkitのWeakReferenceMessengerは結構とっつきやすく作られていてすんなりと実装できました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?