Reputation: 6081
I am making a WinForms program, with an architectural pattern quite similar to MVVM. The main difference is that class I am using as model, also acts as a user control. I know this might not be the most awesome setup, but it is what I have to work with.
The problem is, that when the property in the model is changed, the change isn't reflected in the view...
I am suspecting that I haven't implemented INotifyPropertyChanged
correctly, but I can't really see anything wrong. I hope you guys can...
Model
public partial class ModelAndUserControl : UserControl, INotifyPropertyChanged
{
private decimal _price;
public ModelAndUserControl()
{
InitializeComponent();
}
// Implement INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void InvokePropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
{
PropertyChanged(this, e);
}
}
// Changes in this property, should be reflected in the view
public decimal Price
{
get { return _price; }
set
{
_price = value;
InvokePropertyChanged(new PropertyChangedEventArgs("Price");
}
}
}
View-Model
public class MyViewModel
{
private readonly MyView view;
private ModelAndUserControl model;
public MyViewModel(MyView view, ModelAndUserControl model)
{
this.view = view;
this.model = model;
}
// Debugging reveals that the value of the formatted
// string, changes correctly when the model property changes.
// But the change isn't reflected in the view.
public string FormattedPrice
{
get { return string.format("{0:n0} EUR", model.Price); }
}
}
View
public partial class MyView : UserControl
{
private MyViewModel viewModel;
public MyView()
{
InitializeComponent(ModelAndUserConrol model);
// Create an instance of the view model
viewModel = new MyViewModel(this, model);
// Create the data binding to the price
txtPrice.DataBindings.Add("Text", viewModel, nameof(viewModel.FormattedPrice));
}
}
Upvotes: 0
Views: 615
Reputation: 1209
You need to raise PropertyChanged
on the view model you bind to or the binding wont know when to update. To raise PropertyChanged
on your FormattedPrice
property when the model changes you can do something like this.
public class MyViewModel : INotifyPropertyChanged
{
private readonly MyView view;
private ModelAndUserControl model;
public MyViewModel(MyView view, ModelAndUserControl model)
{
this.view = view;
this.model = model;
this.model.PropertyChanged += Model_PropertyChanged;
}
// Debugging reveals that the value of the formatted
// string, changes correctly when the model property changes.
// But the change isn't reflected in the view.
public string FormattedPrice
{
get { return string.format("{0:n0} EUR", model.Price); }
}
private void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch(e.PropertyName){
case "Price":
InvokePropertyChanged("FormattedPrice");
break;
default:
break;
}
}
// Implement INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void InvokePropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
{
PropertyChanged(this, e);
}
}
}
Upvotes: 2