我遇到了WPF ListView的绑定问题。视图模型实现INotifyPropertyChanged以在数据更新时触发。但它包含一个不实现INotifyPropertyChanged的类型(“Person”)的可观察集合。
ListView在启动后显示我的绑定人员,这很好。但是在更改了模型的数据(人的年龄)后,我不知何故需要手动更新视觉表示/绑定 - 这是我的问题。
如果有人能让我走向正确的方向,我将不胜感激,谢谢!
模型非常简单:
// does not implement INotifyPropertyChanged interface
class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
PersonList是一个ObservableCollection,它通过ItemsSource绑定到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>
视图的代码隐藏将“年龄增长”委托给viewmodel。在模型数据发生这种变化之后,我需要以某种方式更新GUI,这就是我的问题:
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);
}
}
完成后,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));
}
}
答案 0 :(得分:3)
你可以尝试Items.Refresh();
,但我会重新考虑我的课程设计,尤其是你的视图模型和模型。为什么你的模型没有实现INotifyPropertyChanged?为什么不以1:1的比例将模型包装在视图模型中?
目前你正在研究WPF,如果你有充分的理由,你应该这样做。
答案 1 :(得分:2)
当您更改存储在ObservableCollection中的Person实例的属性时,还需要在INotifyPropertyChanged
类上实现Person
以更新UI。
public class Person : INotifyPropertyChanged
{
private string _name;
private string _age;
public string Name {
get {
return _name;
}
set{
_name = value,
OnPropertyChanged();
}
}
public int Age {
get {
return _age;
}
set{
_age= value,
OnPropertyChanged();
}
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}