2010-08-17 13 views
8

Ho un modello di vista che implementa INotifyPropertyChanged. Su questo viewModel è una proprietà chiamata SubGroupingView. Questa proprietà è associata all'elemento selezionato di una casella combinata. Quando cambio la casella combinata, la proprietà sorgente viene aggiornata correttamente, ma quando cambio la proprietà sorgente o quando il controllo è inizializzato, combobox.selectedItem NON sta riflettendo ciò che esiste nella proprietà.
Ecco po 'di codice per iniziare:Combobox SelectedItem non si aggiorna quando cambia la sorgente

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

La proprietà genera l'evento PropertyChanged e l'uscita TraceSource mi mostra che il legame rilevato e trasferito il valore, è solo che la casella combinata non è rifletterla . Qualsiasi idea sarebbe molto gradita!

EDIT:
uscita dalla sorgente traccia è questa:

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) 

Qui è il codice per la proprietà source:

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

    } 
} 

Nota: ViewModelBase implementa INotifyPropertyChange.

RISPOSTA
ho sovraccaricato le ==,! = Operatori, GetHashCode(), e Equals(object) ed ora sta lavorando bene. Grazie per tutto il vostro aiuto!

+0

Per motivi di interesse, prova a impostare ItemsSource prima di SelectedItem nella tua dichiarazione XAML. –

+0

Mi stai seguendo opaco? no luck there – TerrorAustralis

+0

Interessante ... potresti pubblicare uno snippet del tuo ViewModel (in particolare la definizione di SubGroupingView)? – Pwninstein

risposta

15

L'oggetto restituito da SubGroupingView deve essere "uguale" a uno degli oggetti in ComboBox.Items (il che significa che deve trovarsi nella raccolta Columns). Quindi se esegui un "a.Equals (b)", dovrebbe restituire true.

Se sono funzionalmente uguali, ma non restituiscono vero se confrontati, questo è il tuo problema. È necessario restituire lo stesso oggetto o eseguire l'override del metodo Equals (e potenzialmente gli operatori == e! =).

Se questo è il tuo problema, è lo stesso problema di questo question.

+0

WELL vale la taglia! ti voterei ancora di più se potessi !! Quali implicazioni ha questo per MVVM? tutte le VM MVVM implementano un comparatore sulla classe base? (non è possibile assegnare il premio per altre tre ore) – TerrorAustralis

+0

È difficile dirlo in modo definitivo, dal momento che ogni situazione è diversa. el non viene utilizzato in ItemsControls, quindi potrebbe non avere importanza se si esegue l'override di Equals. Ma verrai nella stessa situazione se hai fatto una semplice lista . Contiene (qualcosa). Poiché anche Contains sta eseguendo un test di uguaglianza. – CodeNaked

3

È IsSynchronizedWithCurrentItem sul ComboBox impostato su false? Potresti provare a impostare esplicitamente IsSynchronizedWithCurrentItem="True" e vedere se questo aiuta.

+0

Grazie amico, ma senza fortuna, Se ho impostato IsSynchronizedWithCurrentItem, non fa fuoco del setter sulla fonte – TerrorAustralis

+1

Questo mi ha aiutato durante l'aggiornamento del elenco degli articoli e l'indice selezionato è rimasto invariato – Dave

+0

Se lo imposto, viene visualizzato "Impossibile assegnare alla proprietà" Windows.UI.Xaml.Controls.Primitives.Selector.IsSynchronizedWithCurrentItem "." durante l'inizializzazione (È un'applicazione UWP, la proprietà è stata suggerita da Intellisense, quindi esiste) –

0

La risposta di @CodeNaked è corretta. Ma nel mio caso basta sovrascrivere Object.Equals lancia StackOverflowException. Penso che l'intera risposta sia implementare full IEquatable che significa implementare il suo metodo Equals e sovrascrivere i metodi Object.Equals (Object) e Object.GetHashCode come in this example (vedere la fine della sezione "Note" - "Note per gli implementatori" - e " Esempi "sezione).

Problemi correlati