【WPF覚書】双方向データバインディング


はじめに

前回の記事で以下のように締めくくりましたけど、自動的に反映されるようにするには、もう少し修正が必要でした。

MainViewModel.BindTextを動的に変更すると、それに合わせてLabelのContentプロパティにも自動的に反映される。

XAML

まずはユーザからの入力値をViewModelへ反映したいので、TextBoxを追加します。
さらにXAML(UI)の値がバインドしたViewModelへ反映されるようにバインドのパラメータを追加します。

MainView.xaml
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <TextBox x:Name="textBox" Margin="0,0,0,0" TextWrapping="Wrap" Text="{Binding BindText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" AcceptsTab="True" AcceptsReturn="True"/>
    <Label Content="{Binding BindText, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Margin="0,0,0,0" Grid.Row="1"/>
</Grid>

ViewModel

ViewModelの方も値の変更をXAMLに伝えてあげる必要があります。

MainViewModel.cs
using System.ComponentModel;

    :

class MainViewModel : INotifyPropertyChanged
{
    private string _bindText = "てきとうな初期値";
    public String BindText
    {
        get
        {
            return this._bindText;
        }
        set
        {
            this._bindText = value;
            this.OnPropertyChanged(nameof(BindText));

            return;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged = null;
    protected void OnPropertyChanged(string info)
    {
        this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(info));
    }
}

完成

これで、TextBoxの変更がすぐさまLabelに反映するはずです。
今回ViewModelで追加した部分はBaseViewModelみたいなクラスとして分離しておけば、ViewModelが複数になっても対応するのが簡単になると思います。