Пользовательский интерфейс не обновляется даже при возникновении событий CollectionChanged или PropertyChanged - PullRequest
0 голосов
/ 06 ноября 2011

Фон, из MSDN:

ObservableCollections CollectionChanged событие будет инициировано только когда свойства ObservableCollection изменены (дополнение, удаление элемента) и не при изменении свойств существующих элементов.

Облом , потому что мне нужен пользовательский интерфейс для обновления при изменении определенного свойства существующего элемента. Я пытался запустить оба события CollectionChanged и PropertyChanged, но ни один из них не работал.

Моя ситуация:

В моем приложении listbox привязано к observablecollection, где видимость элементов зависит от свойства "Favorite" каждого элемента, использующего BoolToVisibilityConverter. XAML:

                <ListBox x:Name="FavoritesListBox"
                     Margin="0,0,-12,0"
                     ItemsSource="{Binding FeedItemOCollection}"
                     SelectionChanged="FavoritesListBox_SelectionChanged">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Name="FavoritesStackPanel"
                                    Margin="0,0,0,17" Visibility="{Binding Favorite, Converter={StaticResource BooltoVisibilityConverter}}">
                            <TextBlock Text="{Binding Title}"
                                       TextWrapping="Wrap"
                                       Margin="12,0,0,0"
                                       Style="{StaticResource PhoneTextLargeStyle}" />
                            <TextBlock Text="{Binding PublishDate,Converter={StaticResource DateTimeToDateConverter}}"
                                       TextWrapping="Wrap"
                                       Margin="12,-6,12,0"
                                       Style="{StaticResource PhoneTextSmallStyle}" />
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

Примечание. Этот объект инициализируется в App.Xaml.cs и поэтому является глобальным для всего приложения. Это может быть необычной вещью, которая заставляет вещи не работать для меня.

Как только происходит первоначальная привязка, изменение значения свойства Favorite элемента не приводит к тому, что элемент отображается или исчезает из списка избранного, как того требует причина, указанная в начале сообщения. Это ожидается.

Чтобы обойти это, я попытался запустить оба события CollectionChanged и PropertyChanged, когда свойство Favorite изменяется, чтобы пользовательский интерфейс обновлялся, но ни один из них не работал, и я запутался, почему нет. Мне удалось обойти мою проблему, добавив и удалив элемент из ObservableCollection, но очевидно, что это хак. Код:

public void MarkFavorite(FeedItem feedItem)
    {
        try
        {
            feedItem.Favorite = true;
            //CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));   <-- why doesn't this work?
            //PropertyChanged(this, new PropertyChangedEventArgs("Count"));  <-- why doesn't this work?
            this.Remove(feedItem);   <-- this works, but is a hack
            this.Add(feedItem);   <-- this works, but is a hack

            SaveToIso();
        }
        catch (Exception exception)
        {
            //TODO: Log this.
        }
    }

Почему не работают события? Большое спасибо заранее.

1 Ответ

2 голосов
/ 06 ноября 2011

Ваш класс FeedItem должен реализовывать интерфейс INotifyPropertyChanged, а свойство Favorite должно выглядеть следующим образом:

private bool _Favorite;

private bool _Favorite;
public bool Favorite
{
    get { return _Favorite; }
    set
    {
        _Favorite = value;
        if (PropertyChanged != null)
           PropertyChanged(this, new PropertyChangedEventArgs("Favorite"));
    }
}

Или вы можете извлечь метод

private void OnPropertyChanged(string propertyName)
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

и ваша собственность будет выглядеть так:

private bool _Favorite;
public bool Favorite
{
    get { return _Favorite; }
    set
    {
        _Favorite = value;
        OnPropertyChanged("Favorite");
    }
}
...