Combobox SelectedItem не обновляется при изменении источника

У меня есть модель просмотра, которая реализует INotifyPropertyChanged. На этом viewModel - это свойство, называемое SubGroupingView. Это свойство привязано к выбранному элементу поля со списком. Когда я меняю поле со списком, свойство источника обновляется нормально, но когда я изменяю свойство источника или когда элемент управления инициализируется, combobox.selectedItem НЕ отражает то, что существует в свойстве.
Вот код, который поможет вам началось:

<ComboBox Grid.Column="3" Grid.Row="1" 
          Margin="0,1,4,1" 
          SelectedItem="{Binding Path=SubGroupingView, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, diag:PresentationTraceSources.TraceLevel=High}" 
          ItemsSource="{Binding Columns}" 
          DisplayMemberPath="DisplayName">

Свойство вызывает событие PropertyChanged, и вывод TraceSource показывает мне, что привязка обнаружила его и передала значение, просто поле со списком не отражает его. Любые идеи приветствуются!

РЕДАКТИРОВАТЬ:
вывод из источника трассировки следующий:

System.Windows.Data Warning: 91 : BindingExpression (hash=23631369): Got PropertyChanged event from ReportViewModel (hash=52844413)  
System.Windows.Data Warning: 97 : BindingExpression (hash=23631369): GetValue at level 0 from ReportViewModel (hash=52844413) using RuntimePropertyInfo(SubGroupingView):         DataColumnViewModel (hash=58231222)  
System.Windows.Data Warning: 76 : BindingExpression (hash=23631369): TransferValue - got raw value DataColumnViewModel (hash=58231222)  
System.Windows.Data Warning: 80 : BindingExpression (hash=23631369): TransferValue - implicit converter produced DataColumnViewModel (hash=58231222)  
System.Windows.Data Warning: 85 : BindingExpression (hash=23631369): TransferValue - using final value DataColumnViewModel (hash=58231222)  

Вот код исходного свойства:

public class ReportViewModel : ViewModelBase, IReportTemplate
{
    public DataColumnViewModel SubGroupingView
    {
        get
        {
            return GetViewModel(_report.SubGrouping);
        }
        set
        {
            if (_report.SubGrouping == value.ColumnName)
                return;
            _report.SubGrouping = value.ColumnName;
            RefreshDataSeries();
            base.OnPropertyChanged("SubGroupingView");
            base.OnPropertyChanged("IsReady");
        }

    }
}

Примечание: ViewModelBase реализует INotifyPropertyChange.

ОТВЕТ
Я перегрузил операторы ==,! =, GetHashCode() и Equals(object), и теперь они работают нормально. Спасибо за всю твою помощь!


person TerrorAustralis    schedule 17.08.2010    source источник
comment
Ради интереса попробуйте установить ItemsSource перед SelectedItem в своем объявлении XAML.   -  person Matt Hamilton    schedule 17.08.2010
comment
Ты преследуешь меня, Мэтт? там не повезло   -  person TerrorAustralis    schedule 17.08.2010
comment
Интересно ... не могли бы вы опубликовать фрагмент вашей ViewModel (в частности, определение SubGroupingView)?   -  person Mark Carpenter    schedule 17.08.2010
comment
Как изменить свойство источника? Действительно ли это объект из списка, а не его копия?   -  person Maxim Alexeyev    schedule 18.08.2010
comment
Поскольку это подход ViewModel, объект создается. Я попробую использовать свойство Columns списка   -  person TerrorAustralis    schedule 18.08.2010
comment
Использование объекта из списка не помогло :(   -  person TerrorAustralis    schedule 19.08.2010


Ответы (3)


Объект, возвращаемый из вашего SubGroupingView, должен быть «равен» одному из объектов в ComboBox.Items (что означает, что он должен быть в вашей коллекции Columns). Поэтому, если вы выполните «a.Equals (b)», он должен вернуть true.

Если они функционально одинаковы, но не возвращают true при сравнении, то это ваша проблема. Вам нужно будет либо вернуть тот же объект, либо переопределить метод Equals (и, возможно, операторы == и! =).

Если это ваша проблема, это та же проблема, что и в этом вопросе.

person CodeNaked    schedule 20.08.2010
comment
ХОРОШО стоит награды! Я бы проголосовал за вас еще больше, если бы мог !! Какие последствия это имеет для MVVM? должны ли все виртуальные машины MVVM реализовывать компаратор в базовом классе? (не могу назначить награду еще три часа) - person TerrorAustralis; 20.08.2010
comment
Трудно сказать однозначно, поскольку все ситуации индивидуальны. Если ваша ViewModel не используется в ItemsControls, то не имеет значения, переопределяете ли вы Equals. Но вы бы столкнулись с той же ситуацией, если бы сделали простой List ‹MyViewModel› .Contains (something). Поскольку Contains также выполняет проверку на равенство. - person CodeNaked; 20.08.2010

Возможно, IsSynchronizedWithCurrentItem на вашем ComboBox установлено на false? Вы можете попробовать явно установить IsSynchronizedWithCurrentItem="True" и посмотреть, поможет ли это.

person Zach Johnson    schedule 17.08.2010
comment
Спасибо, приятель, но не повезло, если я установил IsSynchronizedWithCurrentItem, он не срабатывает установщика на источнике - person TerrorAustralis; 17.08.2010
comment
Это помогло мне при обновлении списка элементов, и выбранный индекс остался прежним. - person Dave; 08.03.2013
comment
Если я установил его, мне не удалось назначить свойство Windows.UI.Xaml.Controls.Primitives.Selector.IsSynchronizedWithCurrentItem. во время инициализации (это приложение UWP, свойство было предложено Intellisense, поэтому оно существует) - person II ARROWS; 17.02.2018

Ответ @CodeNaked правильный. Но в моем случае просто переопределение Object.Equals вызывает исключение StackOverflowException. Я думаю, что весь ответ заключается в реализации полного IEquatable, что означает реализацию его метода Equals и переопределение методов Object.Equals (Object) и Object.GetHashCode, как в этот пример (см. конец раздела« Примечания »-« Примечания для разработчиков »- и раздел« Примеры »).

person Alex34758    schedule 26.07.2016