I have a binding problem with the WPF ListView. The view model implements INotifyPropertyChanged to get triggered on data updates. But it contains an observable collection of a type ("Person") that does NOT implement INotifyPropertyChanged.
The ListView shows up my bound persons after startup, that is fine. But after having changed the model's data (person's age), I somehow need to manually update the visual representation/binding - here's my problem.
I would appreciate if someone could kick me into the right direction, thank you!
The model is really simple:
// does not implement INotifyPropertyChanged interface
class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
The PersonList is an ObservableCollection that is bound via ItemsSource to the ListView:
<ListView x:Name="ListViewPersons" ItemsSource="{Binding PersonList}">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"></GridViewColumn>
<GridViewColumn Header="Age" DisplayMemberBinding="{Binding Age}"></GridViewColumn>
</GridView>
</ListView.View>
</ListView>
The view's codebehind delegates the "age growing" to the viewmodel. After this change in the model's data, I need to update the GUI somehow, and here's my problem:
private void Button_Click(object sender, RoutedEventArgs e)
{
...
// increasing the age of each person in the model
viewModel.LetThemGetOlder();
**// how to update the View?**
// does not work
ListViewPersons.GetBindingExpression(ListView.ItemsSourceProperty)
.UpdateTarget();
// does not work either
ListViewPersons.InvalidateProperty(ListView.ItemsSourceProperty);
}
}
To be complete, the ViewModel:
class ViewModel : INotifyPropertyChanged
{
public ViewModel()
{
PersonList = new ObservableCollection<Person>
{
new Person {Name = "Ellison", Age = 56},
new Person {Name = "Simpson", Age = 44},
new Person {Name = "Gates", Age = 12},
};
}
internal void LetThemGetOlder()
{
foreach (var p in PersonList)
{
p.Age += 35;
}
}
private ObservableCollection<Person> _personList;
public ObservableCollection<Person> PersonList
{
get { return _personList; }
set
{
_personList = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
You can try Items.Refresh(); but i would reconsider my class design, especially your viewmodel and models. Why don't your models implement INotifyPropertyChanged? Why don't you wrap your models in view models on a 1:1 basis?
Currently you are working around WPF and you should only do that if you have a good reason.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With