Привязки WPF не будут обновляться, если я не пересоздаю весь список? - PullRequest
0 голосов
/ 01 сентября 2009

Справочная информация:

У меня есть List<T> в моей ViewModel, определенной как ...

private List<FooBar> _fooBars;

public List<FooBar> FooBars
{
    get { return _fooBars; }
    set
    {
        if (value == _fooBars) return;
        _fooBars = value;
        OnPropertyChanged("FooBars");
    }
}

FooBar определяется как ...

public class FooBar
{
    public string FooBarProperty { get; set; }
    // more properties here
}

Между тем, у меня есть GridView, который связывается с этим списком.

<ListView
    ItemsSource="{Binding FooBars}">
    <ListView.View>
        <GridView
            <GridViewColumn
                Header="Foo Bar Prop"
                DisplayMemberBinding={Binding FooBarProperty} />
            <!--more columns here-->
        </GridView>
    </ListView.View>
</ListView>

Я запускаю свое приложение, и все это прекрасно работает. Мои FooBarProperties заполняются как ожидалось.

Проблема:

В ответ на некоторые действия пользователя. Я редактирую один из FooBar объектов в FooBars и вызываю OnPropertyChanged(), чтобы сообщить WPF, что я хочу обновить привязки.

FooBars[2].FooBarProperty = "Some new text here";
OnProperChanged("FooBars"); // WPF is not listening to this :(

Только одна проблема: это полностью не работает. GridView никогда не обновляется.

Обходной путь:

После сильных царапин на голове (а также стук и ругань стола) я предложил следующую замену:

FooBars[2].FooBarProperty = "Some new text here";
FooBars = FooBars.Select(fb => fb).ToList(); // this works but why is it necessary?

Работает как брелок, но зачем мне это делать?

ПРИМЕЧАНИЕ. Я пытался переключиться с List<FooBar> на ObservableCollection<FooBar>, но это не имело никакого значения.

Мои вопросы:

Очень просто, зачем мне этот сумасшедший код, который в основном копирует список в себя, чтобы обновить мои привязки?

Есть ли лучший способ форсировать обновление?

Спасибо.

РЕДАКТИРОВАТЬ - Окончательное решение:

Благодаря ответу @ Botz3000, приведенному ниже, я переключил FooBars обратно на ObservableCollection<FooBar> и изменил FooBar, чтобы он реализовал INotifyChanged. Все работает так, как должно, и не требуется никакого странного копирования списка.

1 Ответ

3 голосов
/ 01 сентября 2009

Если вы не меняете объект, который хранится в самом ObservableCollection, а скорее его свойство, событие CollectionChanged не будет инициировано.

Ваш FooBarProperty тоже нуждается в PropertyChanged("FooBarProperty"). Поскольку элементы списка привязываются к этому свойству, для этого им потребуются уведомления.

...