WinForms: データバインド

C#
この記事は約5分で読めます。
スポンサーリンク

コントロールとデータを紐づけることをデータバインドといいます。
データバインドすることで、コントロール上の値を変更すればデータも自動で変更されるようになります。また、データを変更すればコントロール上の値も自動で変更されるようになります。
データバインドにより、自動的に変更されるようになるので、コード量を減らすことができます。

View-ViewModel-Modelの構成とし、バインド対象のデータをViewModelに配置しています。

スポンサーリンク

Model

データに対応するModelクラスを作成します。

public class Item
{
    public bool Done { get; set; }

    public string Name { get; set; }

    public string Detail { get; set; }
}
スポンサーリンク

View

ViewModelのインスタンスを作成し、「View上のコントロール」と「ViewModelのデータプロパティ」をバインドします。

View: コントロールViewModel: データ
nameTextBox_viewModel.Name
detailRichTextBox_viewModel.Detail
todoGridView_viewModel.Items

データバインドすることで、各コントロールの値はViewModelのデータに自動的に反映されるので、addButton_Clickでコントローラの値をデータに格納するコードが不要になります。

public partial class MainView : Form
{
    private MainViewModel _viewModel = new MainViewModel();

    public MainView()
    {
        InitializeComponent();

        nameTextBox.DataBindings.Add(nameof(nameTextBox.Text), _viewModel, nameof(_viewModel.Name));
        detailRichTextBox.DataBindings.Add(nameof(detailRichTextBox.Text), _viewModel, nameof(_viewModel.Detail));
        todoGridView.DataBindings.Add(nameof(todoGridView.DataSource), _viewModel, nameof(_viewModel.Items));
    }

    private void addButton_Click(object sender, EventArgs e)
    {
        _viewModel.Items.Add(new Item { Name = _viewModel.Name, Detail = _viewModel.Detail });
    }
}
スポンサーリンク

ViewModel

バインド対象のデータをViewModel上に配置します。このデータをViewから呼び出します。

NameとDetailプロパティに関しては、コードでの変更を画面に反映させるために、PropertyChangedイベントを発生させる必要があります。こうすることで、UI→データ、データ→UIの双方向のデータバインドとなります。

public class MainViewModel : INotifyPropertyChanged
{
    private string _name = string.Empty;

    private string _detail = string.Empty;

    public event PropertyChangedEventHandler PropertyChanged;

    public string Name
    {
        get { return _name; }
        set
        {
            if (_name == value) return;

            _name = value;
            if(PropertyChanged != null)
            {
                // コードでの変更を画面に反映させるために必要(データ→UI)
                PropertyChanged(this, new PropertyChangedEventArgs(nameof(Name)));
            }
        }
    }

    public string Detail
    {
        get { return _detail; }
        set
        {
            if (_detail == value) return;

            _detail = value;
            if (PropertyChanged != null)
            {
                // コードでの変更を画面に反映させるために必要(データ→UI)
                PropertyChanged(this, new PropertyChangedEventArgs(nameof(Detail)));
            }
        }
    }

    public BindingList<Item> Items { get; set; } = new BindingList<Item>();
}

コメント

タイトルとURLをコピーしました