2011-05-25 4 views
2

En XAML J'ai un combobox défini comme:C# MVVM Combobox

<ComboBox x:Name="UsernameComboBox" 
      ItemsSource="{Binding Users}" 
      DisplayMemberPath="Username" 
      SelectedItem="{Binding Path=SelectedName, Mode=TwoWay}"/> 

En ce moment, il ne montre aucun élément sélectionné par défaut.

Je remplir la zone de liste déroulante avec une liste:

public List<User> Users 
{ 
    get 
    { 
     return _userRepository.RetrieveUsers(); 
    } 
} 

public List<User> RetrieveUsers() 
{ 
    _users = (from Users in _db.Users select Users).ToList(); 

    return _users; 
} 

Les utilisateurs appropriés étant le ItemSource pour le combobox. Puis, dans le XAML, j'ai défini SelectedItem et l'ai lié à une propriété appelée Nom sélectionné.

Dans le code, cela ressemble:

private User _selectedName; 
    public User SelectedName 
    { 
     get 
     { 
      return _selectedName; 
     } 
     set 
     { 
      if (_selectedName == value) return; 
      _selectedName = value; 
      OnPropertyChanged("SelectedName"); 
     } 
    } 

Comment puis-je obtenir mon combobox pour montrer un selectedItem au démarrage?

Répondre

2

Un problème que je peux voir est que chaque fois que la propriété Users est accédée, la méthode RetrieveUsers() est invoquée qui réexécute votre requête de base de données. Cela va perturber votre liaison SelectedItem qui s'attend à ce que la liste des éléments liés au ComboBox soit inchangée. En d'autres termes, il trouve l'élément sélectionné en évaluant l'égalité du SelectedItem par rapport à la collection d'éléments liés.

Vous devez interroger la base de données une fois ...

public YourClassConstructor() 
{ 
    _users = _userRepository.RetrieveUsers(); 
    _selectedName = _users[0]; 
} 

public List<User> Users 
{ 
    get 
    { 
     return _users; 
    } 
} 

Cela assurera également que le premier élément est sélectionné.

+0

Merci. Très belle réponse en effet. Je vous remercie en particulier de souligner que je continue d'interroger la base de données. Pour cette application au moins, il est très inutile. Aussi, je vais voir comment cela affectera la combobox en utilisant une liste "statique". Merci encore. –

+0

Pas de problème - s'il vous plaît upvote et marquer comme réponse si cela vous a aidé. – ColinE

+0

Terminé. La solution a fonctionné comme un charme. Je peux mourir un homme heureux. –

-1

Il existe quelques performance implications que vous devez prendre en compte lorsque vous choisissez de vous lier à une collection non observable. L'heure de mise à jour est nettement plus rapide si vous vous liez à une collection observable au lieu d'une simple liste.

Vous devriez jeter un oeil à l'aide d'une source d'éléments qui implémente l'interface INotifyCollectionChanged, comme une collection ObservableCollection{T} ou exposer votre source de produits dans votre modèle de vue à l'aide ICollectionView. Jetez également un oeil à ces informations sur Data Binding dans le contexte de MVVM.

Personnellement, je préfère exposer des sources d'éléments dans mes modèles de vue en utilisant ICollectionView. Silverlight fournit la classe PagedCollectionView et WPF fournit la classe ListCollectionView.

public ICollectionView Users 
{ 
    get 
    { 
     if (_viewModelUsers == null) 
     { 
      _viewModelUsers = new PagedCollectionView(_viewModelUsersSource); 
     } 
     return _viewModelUsers; 
    } 
} 
private ICollectionView _viewModelUsers; 
private ObservableCollection<User> _viewModelUsersSource = new ObservableCollection<User>(); 

Vous pouvez ensuite utiliser MoveCurrentToFirst() pour définir l'élément sélectionné après avoir rempli la collection source sous-jacente à l'aide d'un appel à votre référentiel.

+0

La collection ne change pas donc ce n'est pas pertinent. – ColinE