Combobox SelectedItem doesn't update when source changes

13,231

Solution 1

The object returned from your SubGroupingView must be "equal" to one of the objects in the ComboBox.Items (which means it must be in your Columns collection). So if you perform an "a.Equals(b)", it would need to return true.

If they are functionally the same, but not returning true when compared then that's your problem. You would need to either return the same object, or override the Equals method (and potentially the == and != operators).

If this is your issue, it's the same problem as in this question.

Solution 2

Is IsSynchronizedWithCurrentItem on your ComboBox perhaps set to false? You could try explicitly setting IsSynchronizedWithCurrentItem="True" and see if that helps.

Share:
13,231
TerrorAustralis
Author by

TerrorAustralis

Interested in learning C#, VB.NET and starting with wCF applications.

Updated on July 17, 2022

Comments

  • TerrorAustralis
    TerrorAustralis almost 2 years

    I have a viewmodel which implement INotifyPropertyChanged. On this viewModel is a property called SubGroupingView. This property is bound to the selected item of a combo box. When i change the combo box, the source property is being updated fine, but when I change the source property or when the control is initialized, the combobox.selectedItem is NOT reflecting what exists in the property.
    Here is some code to get you started:

    <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">
    

    The property raises the PropertyChanged event and the TraceSource output shows me that the binding detected it and transferred the value, its just that the combobox isn't reflecting it. Any ideas would be most welcome!

    EDIT:
    output from the trace source is this:

    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)  
    

    Here is the code for the source property:

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

    Note: ViewModelBase implements INotifyPropertyChange.

    ANSWER
    I overloaded the ==, != operators, GetHashCode(), and Equals(object) and now it is working nicely. Thanks for all of your help!

    • Matt Hamilton
      Matt Hamilton over 13 years
      Out of interest, try setting the ItemsSource before the SelectedItem in your XAML declaration there.
    • TerrorAustralis
      TerrorAustralis over 13 years
      R u stalking me matt? no luck there
    • Mark Carpenter
      Mark Carpenter over 13 years
      Interesting... could you possibly post a snippet of your ViewModel (specifically the definition of SubGroupingView)?
    • Maxim Alexeyev
      Maxim Alexeyev over 13 years
      How do you change source property? Is it really the object from the list, not any copy of it?
    • TerrorAustralis
      TerrorAustralis over 13 years
      Since its a ViewModel approach, the object is created. I will try using the Columns property of the list
    • TerrorAustralis
      TerrorAustralis over 13 years
      Using an object from the list didnt work :(
  • TerrorAustralis
    TerrorAustralis over 13 years
    Thanks mate, but no luck, If i set IsSynchronizedWithCurrentItem, it doesnt fire of the setter on the source
  • TerrorAustralis
    TerrorAustralis over 13 years
    WELL worth the bounty! i'd vote you up even further if i could!! What implications does this have for MVVM? should all MVVM VMs implement a comparer on the base class? (cant award bounty for another three hours tho)
  • CodeNaked
    CodeNaked over 13 years
    It's hard to say definitively, since every situation is different. If you're ViewModel isn't used in ItemsControls, then it may not matter if you override Equals. But you would run into the same sitution if you did a simple List<MyViewModel>.Contains(something). Since the Contains is performing an equality test also.
  • Dave
    Dave about 11 years
    This helped me when updating the list of items and the selected index stayed the same.
  • II ARROWS
    II ARROWS about 6 years
    If I set it, I get "Failed to assign to property 'Windows.UI.Xaml.Controls.Primitives.Selector.IsSynchronized‌​WithCurrentItem'." during initialize (It's an UWP application, the property was suggested by Intellisense, so it exists)