DataBinding(2)

  

References:

https://intellitect.com/getting-started-model-view-viewmodel-mvvm-pattern-using-windows-presentation-framework-wpf/

Bindings – Keeping it in context

The Binding engine is is what makes the MVVM pattern possible. Bindings are declared in the view, and link properties in the view back to properties in the view model.

public class ViewModel
{
    public string FirstName { get; set; }
}
<TextBlock Text="{Binding Path=FirstName}" VerticalAlignment="Center" HorizontalAlignment="Center"/>

The above code is the start of implementing the MVVM pattern. The Binding sets the value of the Text property to be the value in the FirstName property. If you were to run this code, the TextBlock’s Text would still be empty. This is because there is nothing linking the ViewModel class to the Window. In WPF this link comes from the DataContext property.

In the Window’s constructor we will set its DataContext. If no DataContext is specified on a UI element, it will inherit the DataContext of its parent. So setting the DataContext on the Window will effectively set it for every element within the Window.

public MainWindow()
{
    var viewModel = new ViewModel();
    viewModel.FirstName = "Kevin";
 
    DataContext = viewModel;
    InitializeComponent();
}

Now, running the application, the TextBlock shows “Kevin”.

One of the best things about Bindings is they keep the UI in sync with the data in the view model. Let’s go and update the FirstName property.

public MainWindow()
{
    var viewModel = new ViewModel();
    viewModel.FirstName = "Kevin";
 
    DataContext = viewModel;
    InitializeComponent();
 
    viewModel.FirstName = "Mark";
}

If we run the application the TextBox will still show “Kevin”, not the updated value of “Mark”. Although the property’s value has been changed, there has been no notification to the Binding to update its value. We can fix this by implementing the INotifyPropertyChanged (INPC) interface. This interface has a single event that notifies the bindings that a particular property has changed and any bindings using it should re-evaluate their values.

We can implement it like this:

public class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
 
    public string FirstName { get; set; }
 
    public void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName);
}

Now in the Window’s constructor we notify the view that the property has changed.

public MainWindow()
{
    var viewModel = new ViewModel();
    viewModel.FirstName = "Kevin";
 
    DataContext = viewModel;
    InitializeComponent();
 
    viewModel.FirstName = "Mark";
    viewModel.OnPropertyChanged(nameof(ViewModel.FirstName));
}

Now the binding properly updates to show “Mark”.

However, remembering to raise the event every time you change a property’s value can get very tedious. Because this pattern is so common, many MVVM frameworks provide a base class for your view model classes similar to the following:

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected bool SetProperty<T>(ref T field, T newValue, [CallerMemberName]string propertyName = null)
    {
        if(!EqualityComparer<T>.Default.Equals(field, newValue))
        {
            field = newValue;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            return true;
        }
        return false;
    }
}

This allows us to re-write our FirstName property like this:

public class ViewModel : ViewModelBase
{
    private string _firstName;
    public string FirstName
    {
        get => _firstName;
        set => SetProperty(ref _firstName, value);
    }
}

The INPC event will be raised every time we change the FirstName property.

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值