46 votes

WPF MVVM ComboBox SelectedItem ou SelectedValue ne fonctionne pas

Mise à jour

Après quelques recherches. Ce qui semble être le problème, c'est que la SelectedValue/SelectedItem se produit avant que la source de l'élément n'ait fini de se charger. Si je m'assois à un point d'arrêt et que j'attends quelques secondes, cela fonctionne comme prévu. Je ne sais pas comment je vais résoudre ce problème.

Fin de la mise à jour

J'ai une application en WPF utilisant MVVM avec une ComboBox. Ci-dessous se trouve l'exemple du ViewModel. Le problème que je rencontre est que lorsque nous quittons notre page et que nous revenons, la ComboBox ne sélectionne pas la valeur courante qui est sélectionnée.

Voir le modèle

public class MyViewModel
{
     private MyObject _selectedObject;
     private Collection<Object2> _objects;
     private IModel _model;

     public MyViewModel(IModel model)
    {
         _model = model;
         _objects = _model.GetObjects();
    }

    public Collection<MyObject> Objects
    {
         get
         {
              return _objects;
         }
         private set
         {
              _objects = value;
         }
     }

     public MyObject SelectedObject
     {
          get
          {
              return _selectedObject;
          }
          set
          {
               _selectedObject = value;
          }
      }
 }

Pour les besoins de cet exemple, disons que MyObject possède deux propriétés (Text et Id). Mon XAML pour la ComboBox ressemble à ceci.

XAML

<ComboBox Name="MyComboBox" Height="23"  Width="auto" 
    SelectedItem="{Binding Path=SelectedObject,Mode=TwoWay}" 
    ItemsSource="{Binding Objects}"
    DisplayMemberPath="Text"
    SelectedValuePath="Id">

Quelle que soit ma configuration, lorsque je reviens sur la page et que l'objet est réassemblé, la ComboBox ne sélectionne pas la valeur. L'objet renvoie pourtant le bon objet via le get dans la propriété.

Je ne suis pas sûr qu'il s'agisse d'un problème lié au fonctionnement de la ComboBox et du modèle MVVM. La liaison avec la zone de texte que nous effectuons fonctionne correctement.

2voto

Tim Points 21

J'ai une réponse très simple à ce problème. Tout d'abord, ajoutez le code suivant à la vue IsSynchronizedWithCurrentItem="True".

Ensuite, lorsque vous affectez un nouvel objet dans le ViewModel à cette propriété, SelectedObject doit être enregistré dans cette propriété et non dans le membre privé.

Le modèle de vue Proptery devrait ressembler à ceci

    public Role SelectedObject 
    {
        get { return object; }
        set
        {
            if (value != null)
            {
                if (!object.Equals(value))
                {
                    object = value;
                    OnPropertyChanged(() => SelectedObject );
                }
            }
        }
    }

Cela devrait résoudre le problème.

1voto

Rohit Points 1279

IsSyncronizedWithCurrent=False le fera fonctionner.

1voto

Scott McFadden Points 11

J'ai lutté contre ce problème pendant un certain temps. Dans mon cas, j'utilisais un type complexe (List) comme source d'élément et un KeyType comme valeur sélectionnée. Lors de l'événement de chargement, le KeyType était défini à null. Cela entraînait un dysfonctionnement. Aucun des sous-éléments n'était mis à jour lorsque la clé changeait. Il s'est avéré que lorsque j'ai ajouté une vérification pour m'assurer que la valeur proposée pour KeyType n'était pas nulle, tout a fonctionné comme prévu.

    #region Property: SelectedKey
    // s.Append(string.Format("SelectedKey : {0} " + Environment.NewLine, SelectedKey.ToString()));

    private KeyType _SelectedKey = new KeyType();
    public KeyType SelectedKey
    {
        get { return _SelectedKey; }
        set
        {
            if(value != null )
                if (!_SelectedKey.Equals(value))
                {
                    _SelectedKey = value;
                    OnPropertyChanged("SelectedKey");
                }
        }
    }
    #endregion SelectedKey

1voto

Dummy01 Points 1422

Le type de SelectedValuePath et le SelectedValue doivent être EXACTEMENT identiques.

Si, par exemple, le type de SelectedValuePath est Int16 et le type de la propriété qui se lie à SelectedValue est int il ne fonctionnera pas.

J'ai passé des heures à le trouver, et c'est pourquoi je réponds ici après tant de temps que la question a été posée. Peut-être qu'un autre pauvre gars comme moi avec le même problème pourra le voir.

0voto

Andre Points 11

Vous pouvez également lier votre SelectedIndex à une propriété de votre ViewModel et manipuler votre SelectedItem de cette manière :

        public int SelectedIndex
        {
            get { return _selectedIndex; }
            set
            {
                _selectedIndex = value;
                OnPropertyChanged();
            }    
        }

Et dans votre XAML :

<ComboBox SelectedIndex="{Binding SelectedIndex,Mode=TwoWay}" ... >

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X