当集合中的项目发生更改时,NotifyPropertyChanged在已通过集合的类中

时间:2012-03-13 04:01:38

标签: .net wpf inotifypropertychanged

我正在将一个集合传递给UseSimpleClass。我希望UseSimpleClass属性SimpleClassColCountChecked在传递给UseSimpleClass的集合中的值发生更改时触发。

在现实生活中,集合是一些用户首选项,当他们通过useSimpleClass集合页面时,我想保留他们的首选项。

public partial class MainWindow : Window, INotifyPropertyChanged
{
    private UseSimpleClass useSimpleClass;

    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }


    public MainWindow()
    {
        InitializeComponent();
        List<SimpleClass> simpleCollection = new List<SimpleClass>();
        simpleCollection.Add(new SimpleClass());
        simpleCollection.Add(new SimpleClass());
        simpleCollection.Add(new SimpleClass());
        useSimpleClass = new UseSimpleClass(simpleCollection);
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        useSimpleClass.SimpleClassCol[1].Checked = true;
    }
}

public class SimpleClass : INotifyPropertyChanged
{
    private bool _checked = false;

    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

    public bool Checked 
    { 
        get { return _checked; } 
        set 
        {   
            _checked = value;
            NotifyPropertyChanged("Checked");
            // clearly the next line does not work but that is what I want
            NotifyPropertyChanged("SimpleClassColCountChecked");
        }
    }
}

public class UseSimpleClass : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

    public List<SimpleClass> SimpleClassCol { get; private set; }

    public Int32 SimpleClassColCountChecked
    {
        get
        {
            return (SimpleClassCol.Where(sc => sc.Checked).Count());
        }
    }

    public UseSimpleClass (List<SimpleClass> simpleClassCol)
    { SimpleClassCol = simpleClassCol; }
}

4 个答案:

答案 0 :(得分:1)

这样,您可以在UseSimpleClass中处理SimpleClass的PropertyChanged事件。

public UseSimpleClass (List<SimpleClass> simpleClassCol)
{ 
    SimpleClassCol = simpleClassCol; 
    foreach (var item in SimpleClassCol)
    {
        item.PropertyChanged += HandlePropertyChanged;
    }
}

private void HandlePropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "Checked")
        {
            NotifyPropertyChanged("SimpleClassColCountChecked");
        }
    }

对于source(simpleClassCol)中的每个项目,您开始侦听PropertyChanged事件。可能不是那么贵。

如果它是ListBox(ListView),您可以使用SelectedItems集合来实现此类行为。因此,您将需要两个集合 - 首先包含整个项目,第二个选择项目。

修改 我忘了的主要部分是你应该指定MainWindow的DataContext

Easy app

所以,在

背后的代码中
public MainWindow()
{
    InitializeComponent();
    List<SimpleClass> simpleCollection = new List<SimpleClass>();
    simpleCollection.Add(new SimpleClass());
    simpleCollection.Add(new SimpleClass());
    simpleCollection.Add(new SimpleClass());
    useSimpleClass = new UseSimpleClass(simpleCollection);
    DataContext = useSimpleClass;
}

答案 1 :(得分:1)

您可以使用ObservableCollection<SimpleClass>(来自System.Collections.ObjectModel命名空间)并且您不需要处理更改 - 此集合实现ICollectionChanged接口以及何时更改(添加,编辑,删除项目)数据绑定自动刷新

答案 2 :(得分:1)

您需要我的ObservableComputions库!使用该库,您的代码如下所示:

public partial class MainWindow : Window, INotifyPropertyChanged
{
    private UseSimpleClass useSimpleClass;

    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }


    public MainWindow()
    {
        InitializeComponent();
        ObservableCollection<SimpleClass> simpleCollection = new ObservableCollection<SimpleClass>();
        simpleCollection.Add(new SimpleClass());
        simpleCollection.Add(new SimpleClass());
        simpleCollection.Add(new SimpleClass());
        useSimpleClass = new UseSimpleClass(simpleCollection);
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        useSimpleClass.SimpleClassCol[1].Checked = true;
    }
}

public class SimpleClass : INotifyPropertyChanged
{
    private bool _checked = false;

    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

    public bool Checked 
    { 
        get { return _checked; } 
        set 
        {   
            _checked = value;
            NotifyPropertyChanged("Checked");
            // clearly the next line does not work but that is what I want
            NotifyPropertyChanged("SimpleClassColCountChecked");
        }
    }
}

public class UseSimpleClass : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

    public ObservableCollection<SimpleClass> SimpleClassCol { get; private set; }

    private Computing<int> _simpleClassColCountChecked;
    public Computing<int> SimpleClassColCountChecked
    {
        get
        {
            if (_simpleClassColCountChecked == null)
            {
                _simpleClassColCountChecked = Expr.Is(() => SimpleClassCol.Filtering(sc => sc.Checked).Count).Computing();
            }
            return _simpleClassColCountChecked;
        }
    }

    public UseSimpleClass (List<SimpleClass> simpleClassCol)
    { SimpleClassCol = simpleClassCol; }
}

请注意以下事项:

1)SimpleClassCol的类型更改为ObservableCollection

2)所需的实际值存储在SimpleClassColCountChecked.Value中。 SimpleClassColCountChecked返回INotifyPropertyChanged的实例,并在Value属性更改时通知您。当SimpleClassCol更改或Checked属性更改时,就会发生这种情况。

答案 3 :(得分:0)

是的,ObservableCollection不起作用。

但是有一些框架,女巫试图解决这些问题。

我用Obtics =&gt;做了很好的经历http://obtics.codeplex.com。 这是对这些框架的讨论。 Bindable Linq vs. Continuous Linq

我仍然在寻找这个问题的“最佳”解决方案,所以请分享您的经验:))