テキストボックスで文字を入力すると、
デバックコンソールに入力した文字列が表示されます。
同じ動作のサンプルコードを、
- コードビハインド
- データバインディング(INotifyPropertyChanged)
- データバインディング(ReactiveProperty)
の3種類で作成してみました。
コードビハインド
XAML
<TextBox Width="200"
TextChanged="TextBox_TextChanged"/>
コードビハインド
private void TextBox_TextChanged(object? sender, TextChangedEventArgs e)
{
var tb = sender as TextBox;
Debug.Print(tb?.Text);
}
XAMLのTextChangedイベントで呼び出されるメソッドTextBox_TextChanged()を指定しています。
メソッドの引数は、イベント元のオブジェクトsenderと、イベント情報が含まれるeが渡されます。
senderはobject型なので、TextBoxにキャストしています。
データバインディング(INotifyPropertyChanged)
XAML
<TextBox Width="200"
Text="{Binding Text,
UpdateSourceTrigger=PropertyChanged}" />
UpdateSourceTrigger=PropertyChangedは1文字入力ごとにイベント発生。
デフォルトはフォーカス喪失ですが、このサンプルだとコントロールがTextBoxだけなので、イベントが発生しない為。
ViewModel
using System.Diagnostics;
using Maywork.WPF.Helpers;
namespace WpfSample01;
public class MainWindowViewModel : ViewModelBase
{
private string _text = "";
public string Text
{
get => _text;
set
{
if (_text == value) return;
_text = value;
OnPropertyChanged();
Debug.Print(_text);
}
}
}
Text プロパティはデータバインディングの対象として使用されています。
ViewModel の Text プロパティでは、set アクセサー内で
OnPropertyChanged() を呼び出すことで変更通知を行います。
これによりプロパティの変更が UI に通知され、
TextBox の表示内容が更新されます。
他にも通知を行いたい処理がある場合は、setter 内に処理を追加する形になります。
ただし、setter 内で実行される処理であるため、
重たい処理にならないよう注意しましょう。
データバインディング(ReactiveProperty)
XAML
<TextBox Width="200"
Text="{Binding Text.Value,
UpdateSourceTrigger=PropertyChanged}" />
ViewModel
using System.Diagnostics;
using Maywork.WPF.Helpers;
using Reactive.Bindings;
using Reactive.Bindings.Extensions;
namespace WpfSample01;
public class MainWindowViewModel : ViewModelBaseRx
{
public ReactivePropertySlim<string> Text {get; set;}
= new("");
// コンストラクタ
public MainWindowViewModel()
{
Text
.Subscribe(value => Debug.Print($"{value}"))
.AddTo(Disposable);
}
}
XAML 上では Text.Value をバインディング名として使用し、
ViewModel の ReactivePropertySlim<string> Text とバインドしています。
Text の値が変更されると .Subscribe() 内の処理が実行されます。
.AddTo(Disposable) は Text を自動的に Dispose() するための
仕組みに登録する拡張メソッドです。
INotifyPropertyChanged 版では、プロパティのボイラープレート
(フィールド定義、Getter、Setter)が必要になりますが、
ReactiveProperty を使用するとシンプルで洗練された形で記述できます。
複行入力等
オプション例:改行可・タブ入力可・行末折り返し・縦スクロールバー自動・高さ指定(120)
<TextBox AcceptsReturn="True"
AcceptsTab="True"
TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto"
Height="120"/>
オプション例:改行可・タブ入力可・行末折り返し無し・横スクロールバー自動・縦スクロールバー自動
<TextBox AcceptsReturn="True"
AcceptsTab="True"
TextWrapping="NoWrap"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"/>

コメント