C#のWinFormsでReactivePropertyを使ってコントロールとデータバインディングしてみる。

C# コンピュータ
C#

「データバインディングというとWPFというイメージがありますがWinFormでも出来ますよ」という話

バインドするオブジェクト(データソース)に成れるのは、INotifyPropertyChangedを継承しているクラスであることが条件。
クラスが内包するオブジェクトをジェネリックにすると、クラスを再利用出来るのでは思い試したのが前回の記事に成ります。
C#のWinFormsでINotifyPropertyChangedを使ってコントロールとデータバインディングしてみる。3
INotifyPropertyChangedを継承したクラスのオブジェクトをViewModelとしてWinFormのコントロールとバインドすることが出来ました。今回はジェネリッククラスの勉強がてら、ジェネリッククラスを使うコードに書き換えて...

「INotifyPropertyChangedがバインドできるのであればReactivePropertyでも行けるでしょう」というのが今回の記事の趣旨となります。

プロジェクトの作成

dotnet new winforms -n <プロジェクト名>
cd <プロジェクト名>
dotnet add package ReactiveProperty

いつもはReactiveProperty.WPFですが、今回はWPFではないのでReactivePropertyを追加してみました。

ソースコード

ファイル名:Form1.cs

using Reactive.Bindings;

namespace WinformRP01;
/// <summary>
/// フォーム1
/// </summary>
public partial class Form1 : Form
{
    // テキストボックス1
    TextBox textBox1 = new()
    {
        Location = new (10, 10),
        Size = new (200, 30),
    };
    // ラベル1
    Label label1 = new()
    {
        Location = new (10, 50),
        Size = new (200, 30),
        BorderStyle = BorderStyle.FixedSingle,
    };
    // ボタン1
    Button button1 = new()
    {
        Location = new Point(10, 140),
        Size = new Size(500, 60),
        Text = "button1",
    };
    // 入力文字列
    ReactiveProperty<string> inputText = new("Default");
    /// <summary>
    /// コンストラクタ
    /// </summary>
    public Form1()
    {
        InitializeComponent();

        this.Controls.AddRange([textBox1, label1, button1]);


        textBox1.DataBindings.Add(new Binding("Text", inputText, "Value"));
        label1.DataBindings.Add(new Binding("Text", inputText, "Value"));

        inputText.Subscribe(e=>
        {
            System.Diagnostics.Debug.Print(inputText.Value);
        });
    }
}//class

実行

起動時、バインドされているのでinputTextの初期値のDefaultがテキストボックスとラベルに表示されている。

テキストボックスに「ccc」と入力しタブキーを押しフォーカスをボタンに移動すると、ラベルの値が「ccc」へ変化します。

ViewModel(Form1.cs)側でもinputText.Subscribe()が呼び出されたためDebug.Print()が実行されている。

サンプルコードの機能としてボタンの機能は無いのですが、テキストボックスからフォーカスを移動するために用意しています。
WPFでは一文字入力ごとにSubscribe()が呼び出されていたと思うのですが、挙動が違うのか作り方が違うのか何とも言えません。
個人的に今回のフォーカス喪失後の方が好みの挙動だったりします。

感想

予想通りReactivePropertyが使えました。WinFormsでデータバインディングする場面は少ないとは思いますが、対応するコントロールをMicrosoftのWebページで確認してみると、以下のコントロールが対応している模様。

  1. Button
  2. CheckBox
  3. CheckedListBox
  4. ComboBox
  5. DateTimePicker
  6. DomainUpDown
  7. GroupBox
  8. HScrollBar
  9. Label
  10. LinkLabel
  11. ListBox
  12. ListView
  13. MonthCalendar
  14. NumericUpDown
  15. PictureBox
  16. ProgressBar
  17. RadioButton
  18. RichTextBox
  19. ScrollBar
  20. StatusBar
  21. TextBox
  22. TreeView
  23. VScrollBar

結構な数があります。個人的によく使うコントロールも対応しているみたいなので、試してみたいと思います。

コメント