.NET 4.0 Windows Formで Reactive Extensionsを使う準備
レガシーなFormでもMVVMしたい
過去の資産に縛られたWindowsForms開発をしております。
しかし過去の資産の余りにも・・・。な姿に涙目です。
.NET 4.0、C#4.0縛りです。
少しでも見通しを良くしたいと思い、
MVVMパターンの導入を検討しました。
試しにやってみたら.NET 4.0だと結構躓きましたので記録。
ReactivePropertyを使わないMVVMの準備
「Windows Forms で MVVM」を参考にしたのですが、.NET 4.0縛りの私の環境ではそのままでは使えませんでした。
.NETのRx周りはStandard2.0以降で開花した為か、それ以前の環境ではそのままでは上手く実装できません。
とりあえずここで自作されているFormsMvvmをビルドする最低限のパッケージは以下で導入できました。
nugetパッケージマネージャコンソールにて
Install-Package Rx-Main -Version 2.2.5
Install-Package Microsoft.Bcl
これによって導入されるパッケージは以下でした。
- Microsoft.Bcl v1.1.10
- Microsoft.Bcl.Async v1.0.14
- Rx-Core v2.2.5
- Rx-Interface v2.2.5
- Rx-Linq v2.2.5
- Rx-Main v2.2.5
2018/12/4時点ではMicrosoft.Bclは最新版のVersion1.1.10で導入されました。
よってバージョン指定はしていません。
一緒に入ってくるMicrosoft.Bcl.Build は 1.0.14が導入されましたが、
2018/12/4時点で1.0.21が公開されていますので、場合によってはこれも手動でアップデートする必要が有るかもしれません。
.NET 4.0で Rxに手を出そうとすると Rx-Main Version 2.2.5というのが肝のようです。
Rx-MainはGUIのnuget管理Iから検索すると見つかりません。
https://stackoverflow.com/questions/40004669/system-reactive-rx-net-4-0-on-nuget
ReactivePropertyを使うMVVMの準備
「Windows Forms で MVVM 2 (ReactiveProperty 編)」を参考にReactivePropertyを使おうとすると、最新版(5.3.0)は同様に.NET 4.0では導入できません。
2.9.0以下でエラー無く導入できました。
Install-Package Reactiveproperty -version 2.9.0
後述するエラーに悩まされた結果、
更に
- PresentationCore v4.0.0.0の参照の追加
- ViewModelの一部コードの変更
が発生しました。
変更したコード
using System;
using System.ComponentModel;
using System.Linq;
using System.Reactive.Linq;
using Reactive.Bindings;
namespace reactivepropertytest2
{
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public ReactiveProperty<int> Counter { get; } = new ReactiveProperty<int>();
public ReactiveCommand UpCommand { get; private set; }
public ReactiveCommand DownCommand { get; private set; }
public ViewModel()
{
UpCommand = Counter.Select(_ => Counter.Value < 10).ToReactiveCommand();
UpCommand.Subscribe(_ => Counter.Value++);//(() => Counter.Value++)ではコンパイルエラー
DownCommand = Counter.Select(_ => Counter.Value > 0).ToReactiveCommand();
DownCommand.Subscribe(_ => Counter.Value--);//(() => Counter.Value--)ではコンパイルエラー
}
}
}
ラムダ式の引数を理解してなくてエラーに悩まされた件
UpCommand.Subscribe(() => Counter.Value++);
の部分で
エラー CS1660 ラムダ式 はデリゲート型ではないため、'IObserver<object>' 型に変換できません。
と怒られます。
この記述ではラムダ式の左辺が()
なので引数0を示していますが、
Subscribe
はobject
を引数に取ることを要求しています。
よって上記のエラーが吐かれてます。
ラムダ式を良く分かってなかった私はこれが良く分からずうろうろしてしまいました。
因みにこのobject
はUpCommand.Execute(object)
で渡せますが、
引数を使いたい場合はUpCommand
の型を指定するべきでしょう。
public ReactiveCommand<int> UpCommand { get; private set; }
の様に。
まだエラーは残ってます。
ラムダ式の左辺を()
から_
に変えたところまたエラーが。
'ICommand' は、参照されていないアセンブリに定義されています。
アセンブリ 'PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' に参照を追加する必要があります。
メッセージに従い、PresentationCoreの参照を追加してみます。
これでやっとコンパイルが通ります。
Author And Source
この問題について(.NET 4.0 Windows Formで Reactive Extensionsを使う準備), 我々は、より多くの情報をここで見つけました https://qiita.com/satorimon/items/12230dbbfdf983ac454e著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .