ComboBox items.count ne correspond pas à la source de données (C #)

J’ai un ComboBox qui est lié à un DataSource. Je souhaite append dynamicment des éléments à la ComboBox en fonction de certaines conditions. J’ai donc ajouté les options à une nouvelle liste, puis modifié le DataSource de la ComboBox de la manière suivante:

cbo.DataSource = null; cbo.DataSource = cbos; cbo.DisplayMember = "Title"; cbo.ValueMember = "Value"; 

Ensuite, je vérifie cbo.Items.Count et il n’a pas augmenté – il n’est pas égal au compte de la source de données. Des idées que je peux faire ici? Notez que ceci est WinForms et non asp.net.

Merci

Avez-vous vérifié le compte immédiatement ou plus tard? Il est possible que la ComboBox ne mette pas réellement à jour son contenu tant qu’une opération telle qu’une actualisation de l’UI n’est pas effectuée. Par conséquent, le décompte est désactivé jusqu’à ce moment-là.

Cela peut se produire si vous mettez à jour la source de données avant la création du descripteur pour la ComboBox. J’ai creusé un peu dans le code sur le réflecteur et il apparaît que les éléments ne seront pas mis à jour dans ce cas tant que la zone de liste déroulante n’est pas réellement créée et rendue.

Si quelqu’un rencontre ce problème dans une liste déroulante ajoutée dynamicment, la solution consiste à s’assurer que vous ajoutez la liste déroulante aux contrôles d’un conteneur du formulaire.

En ajoutant “this.Controls.Add (cbo);” au code avant de définir la source de données, le problème disparaît.

J’ai trouvé la cause …

J’ai sorti la ligne cbo.Datasource = null .. et ajouté un cbo.Invalidate () à la fin. Cela a résolu le problème.

Merci à tous pour vos conseils.

 cbo.DataSource = null; cbo.DataSource = cbos; cbo.DisplayMember = "Title"; cbo.ValueMember = "Value"; 

Maintenant, avant de définir cbo.SelectedValue , ou de vous fier aux Items pour être à jour, appelez

 cbo.CreateControl ; 

et les Items seront recalculés.

Le problème est que SelectedValue / SelectedIndex , qui sont des propriétés WinForms, n’acceptent que les valeurs qui sont légales selon la liste Items , mais que celle-ci est construite uniquement après une interaction avec l’interface graphique, c’est-à-dire après l’instanciation d’une “vraie” liste déroulante GUI Windows, c’est-à-dire après obtention d’un handle Windows pour la liste déroulante.

CreateControl force la création du handle Windows, quoi qu’il CreateControl .

Il y a aussi un événement “DataSourceChanged” … peut-être que cela pourrait aider

Juste pour clarifier, appelez-vous la méthode count ()? Après avoir appelé la méthode databind ()

Ce code produit 2 dans la boîte de message pour moi, pouvez-vous l’essayer et voir comment il se comporte?

Vous pouvez le coller dans une application console et append une référence à System.Windows.Forms et System.Drawing .

 using System; using System.Collections.Generic; using System.Windows.Forms; using System.Drawing; namespace SO887803 { static class Program { [STAThread] static void Main() { Application.Run(new MainForm()); } } public partial class MainForm : Form { private Button _Button; private ComboBox _ComboBox; public MainForm() { _Button = new Button(); _Button.Text = "Test"; _Button.Location = new Point(8, 8); _Button.Click += _Button_Click; Controls.Add(_Button); _ComboBox = new ComboBox(); _ComboBox.Location = new Point(8, 40); Controls.Add(_ComboBox); } private void _Button_Click(object sender, EventArgs e) { List items = new List(); items.Add(new Item("A", "a")); items.Add(new Item("B", "b")); _ComboBox.DataSource = null; _ComboBox.DataSource = items; _ComboBox.DisplayMember = "Title"; _ComboBox.ValueMember = "Value"; MessageBox.Show("count: " + _ComboBox.Items.Count); } public class Item { public Ssortingng Title { get; set; } public Ssortingng Value { get; set; } public Item(Ssortingng title, Ssortingng value) { Title = title; Value = value; } } } } 

comboBox1.DataSource = somelist;

int c1 = comboBox1.DataSource.Count; // toujours zéro

BindingContext dummy = this.comboBox1.BindingContext; // Force la mise à jour MAINTENANT!

int c2 = comboBox1.DataSource.Count; // maintenant c’est égal à somelist.Count

J’ai eu le même problème (je travaille avec VS 2005).

Ce que vous devez faire est de définir la source de données sur null, d’effacer les éléments, de réaffecter les membres de source de données, d’affichage et de valeur.

Par exemple

cbo.DataSource = null;

cbo.Items.Clear ();

cbo.DataSource = cbos;

cbo.DisplayMember = “Titre”;

cbo.ValueMember = “Valeur”;

Ancien fil de discussion, mais j’ai essayé certaines de ces solutions, ainsi que suspendre / reprendre le contexte de liaison, se lier à et réinitialiser une source de liaison et tout simplement recharger le formulaire. Personne n’a travaillé pour mettre à jour mon contrôle avec les données nouvellement liées au moment de mon paramétrage .datasource (mon items.count était vide, tout comme l’OP).

Ensuite, j’ai réalisé que ma liste déroulante figurait sur une page à onglet qui était supprimée au début du code, puis ré-ajoutée (après ma liaison de données). L’événement de liaison ne s’est pas produit jusqu’à ce que la page d’onglet ait été ré-ajoutée.

Cela semble évident rétrospectivement, mais il était très difficile à détecter au moment de l’exécution, en raison de l’ordre des appels et de l’impossibilité de voir quand les choses évoluaient.

  ComboBox cbNew = new ComboBox(); cbNew.Name = "cbLine" + (i+1); cbNew.Size = cbLine1.Size; cbNew.Location = new Point(cbLine1.Location.X, cbLine1.Location.Y + 26*i); cbNew.Enabled = false; cbNew.DropDownStyle = ComboBoxStyle.DropDownList; cbNew.DataSource = DBLayer.GetTeams(lineName).Tables[0]; cbNew.DisplayMember = "teamdesc"; cbNew.ValueMember = "id"; Console.WriteLine("ComboBox {0}, itemcount={1}", cbNew.Name, cbNew.Items.Count); // The output displays itemcount = 0 for run-time created controls // and >0 for controls created at design-time gbLines.Controls.Add(cbNew); 

À

  ComboBox cbNew = new ComboBox(); cbNew.Name = "cbLine" + (i+1); cbNew.Size = cbLine1.Size; cbNew.Location = new Point(cbLine1.Location.X, cbLine1.Location.Y + 26*i); cbNew.Enabled = false; cbNew.DropDownStyle = ComboBoxStyle.DropDownList; Console.WriteLine("ComboBox {0}, itemcount={1}", cbNew.Name, cbNew.Items.Count); // The output displays itemcount = 0 for run-time created controls // and >0 for controls created at design-time gbLines.Controls.Add(cbNew); cbNew.DataSource = DBLayer.GetTeams(lineName).Tables[0]; cbNew.DisplayMember = "teamdesc"; cbNew.ValueMember = "id"; 

Les propriétés DataSource, DisplayMember et ValueMember doivent être définies une fois le contrôle ajouté à son conteneur.

Ba salam,

vous pouvez simplement actualiser l’interface utilisateur à l’aide de la fonction preformLayout ();

Exemple:

comboBox1.performLayout ();

salut mohsen s

s’il vous plaît essayez ceci:

 cbo.Parent = ; cbo.DataSource = null; cbo.DataSource = cbos; cbo.DisplayMember = "Title"; cbo.ValueMember = "Value"; MessageBox.Show(ssortingng.Format("itemcount is {0}", cbo.Items.Count); 

Je pense que votre question est la même que celle que j’ai rencontrée aujourd’hui.