ComboBox items.count与数据源不匹配(C#)

我有一个绑定到DataSource的ComboBox。 我想根据特定条件动态添加项目到ComboBox。 所以我所做的是将选项添加到新列表,然后更改ComboBox的DataSource,如下所示:

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

然后,我检查cbo.Items.Count ,它没有增加 – 它不等于DataSource的计数。 我能在这做什么想法? 注意这是WinForms而不是asp.net。

谢谢

您是立即还是稍后检查了伯爵? ComboBox可能实际上没有更新它的内容,直到有一个操作,如UI刷新,因此计数将关闭,直到那个时间。

如果在为ComboBox创建句柄之前更新DataSource,则可能发生这种情况。 我在reflection器上挖了一些代码,看起来在这种情况下不会更新项目,直到实际创建和渲染ComboBox。

如果有人在动态添加的combobox中遇到此问题,答案是确保将combobox添加到表单中容器的控件。

添加“this.Controls.Add(cbo);” 在设置数据源之前的代码,问题就消失了。

我找到了原因……

我拿出了cbo.Datasource = null行..并在最后添加了一个cbo.Invalidate()。 这解决了这个问题。

谢谢大家的建议。

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

现在在设置cbo.SelectedValue之前,或者依赖于Items是最新的,请调用

 cbo.CreateControl ; 

Items将重新计算。

问题是,作为WinForms属性的SelectedValue / SelectedIndex只接受根据Items列表合法的值,但是只在GUI交互之后构建,即在实例化“真正的”Windows GUIcombobox之后,即之后获取combobox的Windows句柄。

无论如何, CreateControl强制创建Windows句柄。

还有一个“DataSourceChanged” – 事件…也许这可能会有所帮助

只是为了澄清你是否在调用databind()方法之后调用count()方法

此代码在消息框中为我生成2,您可以尝试一下,看看它对您的行为如何?

您可以将其粘贴到控制台应用程序中,并添加对System.Windows.FormsSystem.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 String Title { get; set; } public String Value { get; set; } public Item(String title, String value) { Title = title; Value = value; } } } } 

comboBox1.DataSource = somelist;

int c1 = comboBox1.DataSource.Count; //仍为零

BindingContext dummy = this.comboBox1.BindingContext; //现在强制更新!

int c2 = comboBox1.DataSource.Count; //现在它等于somelist.Count

我遇到了同样的问题(我正在使用VS 2005)。

您需要做的是将DataSource设置为null,清除项目,重新分配数据源,显示和值成员。

例如

cbo.DataSource = null;

cbo.Items.Clear();

cbo.DataSource = cbos;

cbo.DisplayMember =“Title”;

cbo.ValueMember =“价值”;

旧线程,但我尝试了一些这些解决方案,以及挂起/恢复bindingcontext,绑定和重置绑定源,只是简单地重新加载表单。 在我的.datasource设置时,没有人使用新绑定的数据更新我的控件(我的items.count为空,就像OP一样)。

然后我意识到我的combobox在一个标签页上,该标签页在代码开头被删除,后来重新添加(在我的数据绑定之后)。 在重新添加标签页之前 ,不会发生绑定事件。

回想起来似乎很明显,但由于调用顺序和无法确定何时发生变化,因此在运行时很难检测到。

  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"; 

将控件添加到其容器后,必须设置DataSource,DisplayMember和ValueMember属性。

巴拉姆,

你可以通过preformLayout()函数简单地刷新UI;

例:

comboBox1.performLayout();

关于mohsen的

请试试这个:

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

我认为你的问题就像我今天遇到的一样。