Как добиться функциональности INotifyPropertyChanged для значений в bool[]?

У меня есть логический массив размера 4, и я хочу привязать каждую ячейку к другому элементу управления. Этот логический массив представляет 4 статуса (false = сбой, true = успех). Этот логический массив является свойством с классом:

class foo : INotifyPropertyChanged {
...
private bool[] _Statuses;
public bool[] Statuses
{
    get {return Statuses;}
    set {
            Statuses = value;
            OnPropertyChanged("Statuses");
        }
}

В XAML есть 4 элемента управления, каждый из которых привязан к одной ячейке массива:

... Text="{Binding Path=Statuses[0]}" ...
... Text="{Binding Path=Statuses[1]}" ...
... Text="{Binding Path=Statuses[2]}" ...
... Text="{Binding Path=Statuses[3]}" ...

Проблема в том, что событие уведомления возникает только тогда, когда я изменяю сам массив, и не возникает, когда я изменяю одно значение в массиве, т. Е. Следующая строка кода вызывает событие:

Statuses = new bool[4];

но следующая строка не вызывает событие:

Statuses [0] = true;

Как я могу вызывать событие каждый раз, когда изменяется одна ячейка?


person yomi    schedule 05.01.2011    source источник


Ответы (3)


Вам нужно выставить свои статусы в качестве индексатора, а затем создать событие изменения свойства, указывающее, что индексатор изменился.

private bool[] _Statuses;

public bool this[int index]
{
    get { return _Statuses[index]; }
    set
    {
        _Statuses[index] = value;

        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(Binding.IndexerName));
    }
}

См. этот пост в блоге:

http://10rem.net/blog/2010/03/08/wpf---silverlight-quick-tip-inotifypropertychanged-for-indexer

person ColinE    schedule 05.01.2011
comment
Вы пропустили скобку, когда вызвали событие изменения свойства. - person Marshall777; 13.11.2013

Он не вызывает событие, потому что Array сам по себе не реализует INotifyPropertyChanged. Вы можете либо использовать другой контейнер, чем примитивный массив (все, что реализует INotifyCollectionChanged понравилось ObservableCollection<T>, должно делать) ИЛИ вам нужно вызывать RaisePropertyChanged("Statuses") каждый раз, когда вы обновляете массив Statuses ИЛИ, как указано в другом ответе, используйте один класс, который реализует INotifyPropertyChanged, который содержит 4 свойства.

person Szymon Rozga    schedule 05.01.2011
comment
Да, использование ObservableCollection будет самым простым способом. - person Wonko the Sane; 05.01.2011
comment
ObservableCollection<T> не уведомляет об изменении значения любого элемента внутри него. - person decyclone; 05.01.2011
comment
@decyclone: ​​он уведомляет, если n-й элемент коллекции перемещен, заменен и т. д., что и делает код OP. Вы правы в том, что это не будет обрабатывать случай, когда T имеет свойства и не реализует INotifyPropertyChanged, но я считал, что это выходит за рамки вопроса. - person Szymon Rozga; 05.01.2011
comment
ты прав. Я не знал, что это будет коллекция типов значений (логических), а не класс. - person decyclone; 05.01.2011

Вы не можете сделать это при использовании Array. Изменение значения любого индекса в Array не вызывает уведомление об изменении, требуемое UI.

Можете ли вы вместо этого использовать класс с четырьмя свойствами, который реализует интерфейс INotifyPropertyChanged?

person decyclone    schedule 05.01.2011