2010-01-10 4 views
3

J'ai un problème avec le fonctionnement d'un ComboBox comme prévu lorsque les données sont liées, et je ne suis pas sûr du problème.ComboBox devient vide après la mise à jour des données, même si les données sont correctement mises à jour

Dans le code ci-dessous, une zone de liste déroulante est créée et reçoit une liste de valeurs liée aux données. Les données sont ensuite liées au formulaire. L'idée est que le ComboBox devrait afficher la liste des options, et quand on est sélectionné, il devrait mettre à jour la source de données, et être indiqué dans la zone de texte d'état. Tout cela semble fonctionner correctement, sauf que ComboBox devient vide après la mise à jour de la valeur, ce que je ne comprends pas.

Lorsque le type de données de la propriété "Selection" est modifié de Int32 en chaîne, il fonctionne exactement comme prévu. Comme Int32, cependant, la boîte devient vide même si elle définit correctement la valeur.

Toute aide comprenant comment résoudre ce problème serait appréciée.

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 

namespace ComboboxDatabindingTest 
{ 
    public partial class Form1 : Form 
    { 
     ComboBox _box; 
     TextBox _status; 
     ValuesDataSource _bsValues; 
     BindingSource _bsObject; 
     Binding _binding; 
     int _selection; 

     public Form1() 
     { 
      _selection = 0; 

      _bsValues = new ValuesDataSource(); 

      _bsObject = new BindingSource(); 
      _bsObject.DataSource = this; 

      _status = new TextBox(); 
      _status.Left = 20; 
      _status.Top = 50; 
      _status.Width = 200; 
      _status.ReadOnly = true; 

      _box = new ComboBox(); 
      _box.Name = "box"; 
      _box.Left = 20; 
      _box.Top = 20; 
      _box.Width = 200; 
      _box.DropDownStyle = ComboBoxStyle.DropDownList; 
      _box.ValueMember = "CodeOrLabel"; 
      _box.DisplayMember = "Label"; 
      _box.DataSource = _bsValues; 
      _binding = _box.DataBindings.Add("SelectedValue", _bsObject, "Selection"); 

      this.Controls.Add(_box); 
      this.Controls.Add(_status); 
     } 

     public int Selection 
     { 
      get { return _selection; } 
      set { _selection = value; _status.Text = value.ToString(); } 
     } 
    } 

    public class Value 
    { 
     private string _code = null; 
     private string _label = ""; 

     public Value(string code, string label) 
     { 
      _code = code; 
      _label = label; 
     } 

     public string Code 
     { 
      get { return _code; } 
     } 

     public string Label 
     { 
      get { return _label; } 
     } 

     public string CodeOrLabel 
     { 
      get { return _code == null ? _label : _code; } 
     } 
    } 

    public class ValuesDataSource : BindingList<Value> 
    { 
     public ValuesDataSource() 
     { 
      base.Add(new Value("1", "California")); 
      base.Add(new Value("2", "Nevada")); 
      base.Add(new Value("3", "Arizona")); 
      base.Add(new Value("4", "Oregon")); 
     } 
    } 
} 

Répondre

2

Cela ne me surprend pas qu'il y ait des difficultés. Avec une liaison SelectedValue, il va essayer de trouver une correspondance (signifiant Equals) entre les ValueMember de chaque (c'est-à-dire CodeOrLabel) et la propriété liée (Selection). Mais il est jamais vrai que (par exemple) "123".Equals(123), donc cela ne correspondra jamais. Donc, il est vraisemblablement décidé que n'est pas un élément sélectionné (puisque aucune correspondance).

Fondamentalement, utilisez string ici, ou utilisez int partout.

+0

Merci! Je savais que ce devait être un problème de type, mais je ne pouvais pas le trouver. Résolu en créant un alias à CodeOrLabel comme CodeInt32 et en l'utilisant comme ValueMember. Cela me permet d'utiliser les mêmes objets Value même lors de la liaison à des propriétés de différents types de données. – Jeremy

Questions connexes