2017-10-06 7 views
0

Je rencontre un problème dans UWP en utilisant MVVM, où j'ai un Combobox avec ItemsSource lié à une collection d'éléments dans mon ViewModel, et aussi dans ma VM est un élément de cette collection que SelectedItem est lié à.Uwp Combobox Rupture de liaison sur le changement de source

Je dois changer à la fois la source des éléments et l'élément sélectionné à volonté dans mon modèle de vue. Le problème est, si le SelectedItem n'existe pas dans le ItemsSource à tout moment, la liaison pour SelectedItem semble rompre définitivement.

Exemple: Disons que j'ai un Comobox qui est lié à ma VM:

<ComoboBox ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}" /> 

Maintenant, dans mon ViewModel, j'ai:

public List<string> Items { get; set; } // Pretend these properties call on OnPropertyChanged 
public string SelectedItem { get; set; } 

public void Initialize() { 
    Items = new List<string> { "A", "B", "C", "D" }; 
    SelectedItem = "B"; 
} 

public void ChangeList() { 
    // This breaks the binding that the Combobox has with SelectedItem 
    Items = new List<string> { "E", "F", "G", "H" }; 

    // This does nothing on the XAML side as the binding is already broken by this poing 
    SelectedItem = "H"; 
} 

Lorsque initialisé, l'application affiche " B "dans la zone de liste déroulante sélectionnée. Si dans le code, disons, je le change en "A", cela reflétera aussi un changement dans la vue. Cependant, quand j'appelle ChangeList() la zone de liste déroulante sera définie à vide et ignorera toutes les modifications que je fais dans le code derrière.

Malheureusement, dans mon cas, la mise en SelectedItem à null avant de mettre à jour la liste des sources ne résout pas mon problème.

Comment procéder pour changer la source et l'élément sélectionné dans la machine virtuelle?

Répondre

0

Lorsque vous modifiez le Items pour une nouvelle collection, le ComboBox doit automatiquement réinitialiser le SelectedItem pour vous. Vous devrez recevoir ce changement et répondre avec un NotifyPropertyChanged.

Essayez de changer votre liant à deux voies:

<ComoboBox ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}" /> 
+0

Je suis d'accord que cela devrait fonctionner comme ça. J'ai observé que 'SelectedItem' est défini sur' null' quand je mets le mode de liaison à 'TwoWay', mais après que la liaison semble rester brisée. Changer l'élément dans le modèle de données ne déclenche plus un 'get' sur la liste déroulante et rien n'est sélectionné. –

0

utilisateur ObservableCollection au lieu d'une liste

SelectedItem public string {get; ensemble; }

private ObservableCollection<string> _Items = new ObservableCollection<string> { "A","B", "C"}; 
    public ObservableCollection<string> Items 
    { 
     get 
     { 
      return _Items; 
     } 

     set 
     { 
      if (value == _Items) 
      { return; } 
      _Items = value; 
      RaisePropertyChanged(nameof(Items)); 
     } 
    } 

Ok, je ne suis pas sûr de ce que votre code ressemble mais si vous remplacez le ItemsSource de votre ComboBox alors vous pouvez faire ceci:

Items.Clear();

articles = new ObservableCollection { "D", "E", "F"};

SelectedItem = Items.FirstOrDefault (c => c == "D");

Vous devrez faire votre propre erreur de vérifier si « D » existe dans la collection en faisant Items.Any (c => c == « D »); Cela retournera un vrai ou faux. Si elle retourne vrai alors allez-y et réglez votre élément sélectionné: SelectedItem = Items.FirstOrDefault (c => c == "D");

Maintenant, gardez à l'esprit "D" peut être n'importe quelle chaîne. string searchString = ""; Alors maintenant vous pouvez remplir l'instruction Lambda comme ceci: SelectedItem = Items. FirstOrDefault (c => c == searchString);

Espérons que ça aide.

+0

Malheureusement, cela ne résout pas le problème. Je ne suis pas en train d'ajouter/supprimer les éléments dans la source, je le remplace par une nouvelle liste. Cela fait que le fichier 'SelectedItem' actuel n'existe plus dans la liste, et c'est ce que je pense casse la liaison –

+0

Ok, je ne sais pas exactement à quoi ressemble votre code, mais si vous supprimez l'ItemSource, vous devrez chercher le élément dans votre ObservableCollection. Donc, ce que je ferais est de faire ceci: – 7VNT