在MVVM中,什么打算刷新属性NumberOfAdults和NumberOfChildren以在UI上更新?更一般地说,People视图模型如何捕获更新并刷新依赖于OberservableCollection<Person>
上的内容的属性?
该解决方案需要更高级的XAML绑定语法使用。它是什么?
人物视图模型
public class Person : INotifyPropertyChanged
{
private int _age;
public int Age
{
get { return _age; }
set { _age = value; NotifyPropertyChanged("Age"); }
}
private string _name;
public string Name
{
get { return _name; }
set { _name = value; NotifyPropertyChanged("Name"); }
}
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
人物视图模型
using System;
using System.ComponentModel;
using System.Collections.ObjectModel;
public class PeopleViewModel : INotifyPropertyChanged
{
public PeopleViewModel()
{
People.Add(new Person { Name = "Happy", Age = 12 });
People.Add(new Person { Name = "Sleepy", Age = 15 });
People.Add(new Person { Name = "Sneezy", Age = 17 });
People.Add(new Person { Name = "Grumpy", Age = 45 });
People.Add(new Person { Name = "Dopey", Age = 50 });
People.Add(new Person { Name = "Bashful", Age = 60 });
People.Add(new Person { Name = "Doc", Age = 75 });
}
private ObservableCollection<Person> _people = new ObservableCollection<Person>();
public ObservableCollection<Person> People
{
get { return _people;}
set { _people = value;}
}
public int NumberOfAdults
{
get
{
int count = 0;
foreach (Person p in People)
{
if (p.Age >= 18)
{
count += 1;
}
}
return count;
}
}
public int NumberOfChildren
{
get
{
int count = 0;
foreach (Person p in People)
{
if (p.Age < 18)
{
count += 1;
}
}
return count;
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
主要XAML
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<Label Content="{Binding Path=NumberOfAdults}"></Label>
<Label Content="{Binding Path=NumberOfChildren}"></Label>
<DataGrid ItemsSource="{Binding Path=People}"></DataGrid>
</StackPanel>
</Window>
答案 0 :(得分:0)
这是我的解决方案。它不是很好,但会起作用。我对CollectionChanged事件的ObservableCollection实现了一个回调。在它的回调中,我注册了PropertyChanged事件。
using System;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Diagnostics;
public class PeopleViewModel : INotifyPropertyChanged
{
public PeopleViewModel()
{
People.CollectionChanged += People_CollectionChanged;
// Same as before....
}
void p_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
Person p = (Person)sender;
Debug.WriteLine(String.Format("Update occured on Name: {0} Age: {1}",p.Name,p.Age));
NotifyPropertyChanged("NumberOfAdults");
NotifyPropertyChanged("NumberOfChildren");
}
void People_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
Debug.WriteLine("People_CollectionChanged called.");
if (e.NewItems != null)
{
foreach (Person p in e.NewItems)
{
p.PropertyChanged += p_PropertyChanged;
}
}
if (e.OldItems != null)
{
foreach (Person p in e.OldItems)
{
p.PropertyChanged -= p_PropertyChanged;
}
}
}
// Same as before.
}