NotifyPropertyChanged в классе, который был передан в коллекцию при изменении элемента в коллекции - PullRequest
0 голосов
/ 13 марта 2012

Я передаю коллекцию в 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; }
}

Ответы [ 3 ]

1 голос
/ 13 марта 2012

Вы можете использовать ObservableCollection<SimpleClass> (из System.Collections.ObjectModel пространства имен), и вам не нужно обрабатывать изменения - эта коллекция реализует интерфейс ICollectionChanged, и при его изменении (добавление, редактирование, удаление элементов) привязка данных обновляется автоматически

1 голос
/ 13 марта 2012

Таким образом, вы можете обрабатывать событие PropertyChanged SimpleClass в UseSimpleClass.

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");
        }
    }

Для каждого элемента в источнике (simpleClassCol) вы начинаете прослушивать событие PropertyChanged. Может быть, это не так дорого.

Если это будет ListBox (ListView), вы можете использовать коллекцию SelectedItems для достижения такого поведения. Таким образом, вам понадобятся две коллекции - первая будет содержать целые элементы, вторая - выбранные элементы.

EDIT: Основная часть, которую я забыл - это то, что вы должны указать DataContext вашего MainWindow

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;
}
0 голосов
/ 10 июля 2013

Да, ObservableCollection не работает.

Но есть рамки, которые пытаются решить эти проблемы.

Я получил хороший опыт работы с Obtics => http://obtics.codeplex.com. Вот обсуждение этих рамок. Bindable Linq против непрерывного Linq

Я все еще ищу "лучшее" решение для этой проблемы, поэтому, пожалуйста, поделитесь своим опытом:))

...