当T更新ObservableCollection <t>时,建议刷新其他依赖属性</t>

时间:2013-11-10 06:25:45

标签: wpf

在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>

1 个答案:

答案 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.
}