ダイアログを表示したい
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は結構とっつきやすく作られていてすんなりと実装できました。