かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

InteractionRequestをRxに合流させる

こねたです。

こんなのを用意しておくと捗ります。

using Microsoft.Practices.Prism.Interactivity.InteractionRequest;
using System;
using System.Reactive.Disposables;
using System.Reactive.Linq;

namespace WpfApplication7
{
    public static class InteractionRequestExtensions
    {
        public static IObservable<T> RaiseAsObservable<T>(this InteractionRequest<T> self, T n)
            where T : INotification
        {
            return Observable.Create<T>(o =>
            {
                self.Raise(n, result => o.OnNext(result));
                return Disposable.Empty;
            });
        }

    }
}

例えば、RxCommandが実行されたら確認ダイアログが出てOKが押されたときのみ何かをするといった処理が以下のように書ける!

public class MainWindowViewModel
{
    public ReactiveCommand ConfirmCommand { get; private set; }

    public InteractionRequest<Confirmation> ConfirmRequest { get; private set; }

    public MainWindowViewModel()
    {
        this.ConfirmRequest = new InteractionRequest<Confirmation>();
        this.ConfirmCommand = new ReactiveCommand();

        this.ConfirmCommand
            .SelectMany(_ => this.ConfirmRequest.RaiseAsObservable(new Confirmation
            {
                Title = "確認",
                Content = "コンテンツ"
            }))
            .Where(c => c.Confirmed)
            .Subscribe(_ =>
            {
                Debug.WriteLine("モデルのコードの呼び出し");
            });
    }
}

割といいかも