Prism+ReactivePropertyで簡単WPFアプリケーション開発


#プロジェクトを立ち上げる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684408/5757393f-f340-4500-df57-db5863c5861b.png)

#NuGetでパッケージをインストール
プロジェクトを右クリックして、「NuGetパッケージの管理」から、Prism.CoreとPrism.Unity、ReactivePropertyをインストールする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684408/58dbe106-cea8-6882-30c9-a5e8410a3eb5.png)

##ViewModelを作成

ViewModelの基底クラスViewModelBase.csを作成。

```cs

    using System;
    using System.Reactive.Disposables;
    using Prism.Mvvm;

    public abstract class ViewModelBase : BindableBase, IDisposable
    {

        public ViewModelBase(){ }

        #region "IDisposable"

        public CompositeDisposable disposedValue = new CompositeDisposable();

        protected virtual void Dispose(bool disposing)
        {
            this.disposedValue.Dispose();
        }

        public void Dispose()
        {
            // このコードを変更しないでください。クリーンアップ コードを 'Dispose(bool disposing)' メソッドに記述します
            Dispose(disposing: true);
            GC.SuppressFinalize(this);
        }
        #endregion
```

MainVindowのViewModelを作成する（MainVindowViewModel.cs）。

```csharp

    using Reactive.Bindings;
    using Reactive.Bindings.Extensions;

    public class MainWindowViewModel: ViewModelBase
    {
        public MainWindowViewModel() : base()
        {

            // テキスト
            this.Text = new ReactiveProperty<string>("ボタンを押してみてください。")
                .SetValidateAttribute(() => this.Text)
                .AddTo(this.disposedValue);

            // ボタン
            // Textプロパティにエラーがなくなったらアクティブになる。
            this.RunCommand = new[]
            {
                this.Text.ObserveHasErrors
            }
            .CombineLatestValuesAreAllFalse()
            .ToAsyncReactiveCommand()
            .WithSubscribe(async () =>
            {
                // ボタン押下した時の処理
                await Task.Run(() =>
                {
                    this.Text.Value = "ボタンを押しました。";
                });
            })
            .AddTo(this.disposedValue);
        }

        public ReactiveProperty<string> Text { get; }

        public AsyncReactiveCommand RunCommand { get; }

    }

```

#App

App.xaml

```xml
<prism:PrismApplication 
    x:Class="WpfApp1.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApp1"
    xmlns:prism="http://prismlibrary.com/">
    <Application.Resources>
         
    </Application.Resources>
</prism:PrismApplication>

```

App.cs

```csharp

    using System.Windows;
    using Prism.Unity;
    using Prism.Ioc;
    using Prism.Mvvm;

    /// <summary>
    /// App.xaml の相互作用ロジック
    /// </summary>
    public partial class App : PrismApplication
    {
        protected override Window CreateShell()
        {
            return Container.Resolve<MainWindow>();
        }

        protected override void ConfigureViewModelLocator()
        {
            base.ConfigureViewModelLocator();
            ViewModelLocationProvider.Register<MainWindow, MainWindowViewModel>();
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            base.ConfigureViewModelLocator();
        }
    }
```

ここで、いったんビルドする。

#MainWindow
ウインドウにテキストとボタンを配置して、ViewModelのプロパティとデータバインドする。

```xml
<Window x:Class="WpfApp1.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:prism="http://prismlibrary.com/"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        prism:ViewModelLocator.AutoWireViewModel="True"
        Title="MainWindow" Height="150" Width="400">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="50"/>
            <RowDefinition Height="50"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <!-- ViewModelのTextプロパティとバインドする -->
        <TextBlock Grid.Row="0" Text="{Binding Path=Text.Value,Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
        <!-- ViewModelのRunCommandプロパティとバインドする -->
        <Button Grid.Row="1" Content="ボタン" 
                Command="{Binding Path=RunCommand}"/>
    </Grid>
</Window>


```

# 動作確認
デバッグで動作確認してみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684408/07f04a1b-3b49-7e21-6f2b-188918fd6d5e.png)
↓↓↓ボタンを押すと↓↓↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684408/c90df417-6c0f-75db-14a3-316709587cef.png)

OK！