2009-09-12 9 views
1

J'ai une question de liaison de données intéressante liée à la zone de liste déroulante. J'espère que quelqu'un a une bonne suggestion.Une question de liaison de données ComboBox

J'ai un formulaire simple, il contient un sélecteur de fichiers et une comboxbox. Chaque fois qu'un fichier est sélectionné, je lis une liste de chaînes du fichier vers un objet List et je règle comboBox.DataSource = listOfStrings.

Dans l'événement de chargement de formulaire, j'ai défini comboBox.DataBindings.Add ("SelectedItem", myObject, "PickedValue"); Le but est clair: chaque fois qu'une chaîne est sélectionnée dans la liste déroulante, je veux écrire la chaîne dans myObject.PickedValue.

Voilà toute l'histoire.

Maintenant, je lance le formulaire, plutôt que d'aller chercher un fichier, je vérifie d'abord la liste déroulante. Bien sûr, à ce stade, comboBox.DataSource est null, comboBox.SelectedItem est également null. Mais la liaison de données sur la comboBox est déjà configurée (puisque le paramètre est dans l'événement de chargement de formulaire). Maintenant, mon attention ne peut pas être déplacée de la combobox à nulle part ailleurs.

Je pense que la raison en est, lorsque j'essaie de vérifier la liste déroulante, elle a null comme SelectedItem. Lorsque j'essaie de déplacer le focus vers un autre emplacement, la liaison de données de la zone de liste déroulante est déclenchée. Sous-jacent, il tente de convertir l'élément sélectionné en chaîne et met à jour myObject.PickedValue avec cette chaîne convertie. Comme vous ne pouvez pas convertir une valeur nulle en une chaîne, la validation de la liaison de données échoue, et le mécanisme de validation ne permet pas de déplacer mon focus ailleurs et je suis aspiré à ce moment, je ne peux même pas déplacer un fichier.

Ma question est, quel est le workflow de configuration de liaison normale pour mon scénario d'application pour éviter ce piège? Quel est le bon ordre de mise en place d'une telle liaison de données afin que je puisse vérifier ma liste déroulante avant que sa source de données ne soit remplie par quelque chose? FYI, j'ai essayé de lier myObject.PickedValue à la propriété SelectedText de la liste déroulante (j'ai remarqué que SelectedText est une chaîne et ne sera jamais nulle, même si SelectedItem est null). Mais de façon intéressante, même si je sélectionne quelque chose dans la liste déroulante, SelectedText est toujours une chaîne vide lorsque la liaison de données est déclenchée. Quel est le problème ici?

Merci pour toute aide.

Répondre

1

Cela ne semble pas correct; il devrait être possible de définir une propriété de chaîne sur null. Peut-être le problème de mise au point est ailleurs. Avez-vous essayé de définir un point d'arrêt sur votre setter de la propriété pour confirmer votre théorie?

La propriété SelectedText d'une zone de liste déroulante fait référence au texte qui a été sélectionné dans la partie de texte de la liste déroulante. Cela ne fonctionne que si le style déroulant est défini sur combo. Fondamentalement, c'est le texte sélectionné de la partie de la zone de texte du contrôle combo (la raison pour laquelle une liste déroulante est appelée "combo" est parce que c'est une combinaison d'une zone de texte et d'une liste de sélection). Vous vous attendez normalement à ce que cette propriété soit vide sauf si l'utilisateur modifiait la partie de texte de la liste déroulante.

Si vous voulez une solution de contournement pour ce problème compatible avec une bonne expérience utilisateur, essayez de désactiver la zone de liste déroulante lors du chargement du formulaire, puis de l'activer lors de la sélection d'un fichier.

+0

Merci de me donner une solution de contournement. Je pense que l'idée de désactiver la combobox jusqu'à ce qu'elle soit prête est une bonne idée. Et merci d'expliquer pourquoi la propriété SelectedText ne fonctionne pas pour moi. Je suppose que je vais le prendre comme réponse. – Steve

3

L'échec est un peu plus simple que ce que vous décrivez: votre ComboBox échouera simplement parce qu'il n'y a pas d'élément sélectionné, car il n'y a rien à sélectionner.

Je voudrais juste désactiver le ComboBox s'il n'y a rien à sélectionner. C'est assez facile à faire.N'oubliez pas de connecter un événement PropertyChanged dans votre objet de données; la source de liaison le trouvera automatiquement avec la réflexion.

class MyData 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    // ... 
    public HasListOfStrings { get { return ListOfStrings != null && 0 < ListOfStrings.Count; } } 

    private void LoadListOfStrings 
    { 
     // ... load the list of strings ... 

     if (PropertyChanged) { 
      PropertyChanged(this, "ListOfStrings"); 
      PropertyChanged(this, "HasListOfStrings"); 
     } 
    } 
} 

Dans le concepteur, lier la propriété « Activé » du « ComboBox » à la propriété HasListOfStrings. Vous pouvez le faire en code avec:

listOfStringsComboBox.Bindings.Add ("Enabled", bindingSource, "HasListOfStrings"); 

Je recommande également de modifier la propriété AutoValidate du conteneur (ou contenant du conteneur) à EnableAllowFocusChange.

+0

Merci Larry pour la solution de contournement. L'idée est similaire à celle de Paul et merci particulièrement pour le code. J'ai pris le sien comme la réponse juste parce qu'il a répondu à ma question SelectedText aussi bien. Mais fondamentalement, le vôtre est aussi utile que le sien. À votre santé. – Steve

+0

Content de pouvoir aider! – XXXXX