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.Forms
和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 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);
我认为你的问题就像我今天遇到的一样。