【C#】【Prism】【ReactiveProperty】ViewModelからOpenFileDialogを呼び出す【WPF】【XAML】

唐突ですが,

「MVVM OpenFileDialog」

と検索すると,

ViewModel側でOpenFileDialogを呼び出すだけなのに,

膨大なソースコードの量が書いてある記事が沢山出てきます.

1機能作るのにそんなに時間かけたくないですよね…

今回はそれを解消する内容です.

環境

  • Prism Template Pack v2.1.6
  • ReactiveProperty v5.5.1

導入方法

UI

UIはこんな感じにしました.

<Window x:Class="OpenFileDialogwithPrism.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:prism="http://prismlibrary.com/"
        prism:ViewModelLocator.AutoWireViewModel="True"
        Title="{Binding Title}" Height="60" Width="400">
    
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="40"/>
            <ColumnDefinition Width="1*"/>
        </Grid.ColumnDefinitions>
        
        <Button Content="Open"
                VerticalAlignment="Center"
                Grid.Column="0"/>

        <TextBlock Text=""
                   TextAlignment="Left"
                   VerticalAlignment="Center"
                   Margin="10 0 0 0"
                   Background="LightGray"
                   Grid.Column="1"/>
    </Grid>
</Window>

ViewModel側の処理

ライブラリ一覧

using Prism.Commands;
using Prism.Mvvm;
using Reactive.Bindings;
using System.Windows.Forms;

処理

public class MainWindowViewModel : BindableBase
{
	// デフォルトで付いている処理なので無視してOK
	/* -------------------------------------------- */
	private string _title = "OpenFileDialogwithPrism";
	public string Title
	{
		get { return _title; }
		set { SetProperty(ref _title, value); }
	}
	/* -------------------------------------------- */

	// ボタンクリック用のDelegateCommand
	public DelegateCommand OpenFileDialogCommand { get; private set; }

	// 変更通知用のReactivePropert
	public ReactiveProperty<string> FileName { get; } = new ReactiveProperty<string>();

	public MainWindowViewModel()
	{
		// ボタンクリックした時の処理
		OpenFileDialogCommand = new DelegateCommand(() => VM_OpenFileDialog());
	}

	// OpenFileDialog呼び出しメソッド
	private void VM_OpenFileDialog()
	{
		var openFileDialog = new OpenFileDialog();

		if (openFileDialog.ShowDialog() == DialogResult.OK)
		{
			FileName.Value = openFileDialog.FileName;
		}
	}
}

ViewとViewModelを紐づける

<Window x:Class="OpenFileDialogwithPrism.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:prism="http://prismlibrary.com/"
        prism:ViewModelLocator.AutoWireViewModel="True"
        Title="{Binding Title}" Height="60" Width="400">
    
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="40"/>
            <ColumnDefinition Width="1*"/>
        </Grid.ColumnDefinitions>

        <Button Content="Open"
                VerticalAlignment="Center"
                Grid.Column="0"
                Command="{Binding OpenFileDialogCommand}"/>
        
        <TextBlock Text="{Binding FileName.Value}"
                   TextAlignment="Left"
                   VerticalAlignment="Center"
                   Margin="10 0 0 0"
                   Background="LightGray"
                   Grid.Column="1"/>
    </Grid>
</Window>

Buttonに

Command="{Binding OpenFileDialogCommand}"

を追加,

TextBlockに

Text="{Binding FileName.Value}"

を追加します.

実行