C# ComboBox items.count 与数据源不匹配
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/887803/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ComboBox items.count doesn't match DataSource
提问by Madeleine
I have a ComboBox that is bound to a DataSource. I want to dynamically add items to the ComboBox based on certain conditions. So what I've done is add the options to a new list, and then change the DataSource of the ComboBox like so:
我有一个绑定到数据源的 ComboBox。我想根据某些条件将项目动态添加到 ComboBox。所以我所做的是将选项添加到一个新列表中,然后像这样更改 ComboBox 的数据源:
cbo.DataSource = null;
cbo.DataSource = cbos;
cbo.DisplayMember = "Title";
cbo.ValueMember = "Value";
Then, I check cbo.Items.Count
, and it has not incremented - it does not equal the count of the DataSource. Any ideas what I can do here?
然后,我检查cbo.Items.Count
,它没有增加 - 它不等于数据源的计数。任何想法我可以在这里做什么?
Note this is WinForms and not ASP.NET.
请注意,这是 WinForms 而不是 ASP.NET。
采纳答案by Madeleine
If anyone experiences this problem on a dynamically added combobox, the answer is to ensure that you add the combobox to the controls of a container in the form.
如果有人在动态添加的组合框上遇到此问题,答案是确保将组合框添加到窗体中容器的控件中。
By adding "this.Controls.Add(cbo);" to the code before setting the datasource, the problem goes away.
通过添加“this.Controls.Add(cbo);” 设置数据源之前的代码,问题就消失了。
回答by JaredPar
Did you check the Count immediately or at a later time? There is the possibility that the ComboBox does not actually update it's contents until there is an operation such as a UI refresh and hence the count will be off until that time.
您是立即检查还是稍后检查计数?有可能 ComboBox 在进行 UI 刷新等操作之前不会实际更新其内容,因此在此之前计数将关闭。
On case where this may happen is if you update the DataSource before the Handle is created for the ComboBox. I dug through the code a bit on reflector and it appears the items will not be updated in this case until the ComboBox is actually created and rendered.
如果在为 ComboBox 创建句柄之前更新数据源,可能会发生这种情况。我在反射器上对代码进行了一些挖掘,在这种情况下,在实际创建和呈现 ComboBox 之前,这些项目似乎不会更新。
回答by JaredPar
Just to clarify are you calling the count() method After calling the databind() method
只是为了澄清您是否在调用 databind() 方法之后调用了 count() 方法
回答by Madeleine
I've found the cause...
我已经找到原因了...
I took out the cbo.Datasource = null line.. and added a cbo.Invalidate() at the end. This has solved the problem.
我拿出了 cbo.Datasource = null 行..并在最后添加了一个 cbo.Invalidate() 。这已经解决了这个问题。
Thanks all for the advice.
谢谢大家的建议。
回答by Lasse V. Karlsen
This code produces 2 in the message box for me, can you try it and see how it behaves for you?
此代码为我在消息框中生成 2,您可以尝试一下,看看它对您的表现如何?
You can paste it into a console application, and add a reference to System.Windows.Forms
and System.Drawing
.
您可以将其粘贴到控制台应用程序中,并添加对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<Item> items = new List<Item>();
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;
}
}
}
}
回答by Lasse V. Karlsen
comboBox1.DataSource=somelist;
comboBox1.DataSource=somelist;
int c1=comboBox1.DataSource.Count; // still zero
int c1=comboBox1.DataSource.Count; // 还是零
BindingContext dummy = this.comboBox1.BindingContext;// Force update NOW!
BindingContext dummy = this.comboBox1.BindingContext;// 立即强制更新!
int c2=comboBox1.DataSource.Count; // now it equals somelist.Count
int c2=comboBox1.DataSource.Count; // 现在它等于 somelist.Count
回答by Lasse V. Karlsen
Ba salam,
巴萨拉姆,
you can simply refresh the UI by preformLayout() function;
您可以通过 preformLayout() 函数简单地刷新 UI;
Example:
例子:
comboBox1.performLayout();
comboBox1.performLayout();
regards mohsen s
问候莫森
回答by Lasse V. Karlsen
please try this:
请试试这个:
cbo.Parent = <your panel control>;
cbo.DataSource = null;
cbo.DataSource = cbos; cbo.DisplayMember = "Title";
cbo.ValueMember = "Value";
MessageBox.Show(string.Format("itemcount is {0}", cbo.Items.Count);
I think your question sames like I met today.
我想你的问题和我今天遇到的一样。
回答by Lasse V. Karlsen
I had the same problem (Im working with VS 2005).
我遇到了同样的问题(我正在使用 VS 2005)。
What you need to do is set the DataSource to null, clear the items, reassign the datasource , display and value members.
您需要做的是将 DataSource 设置为 null,清除项目,重新分配 datasource 、 display 和 value 成员。
Eg
例如
cbo.DataSource = null;
cbo.DataSource = null;
cbo.Items.Clear();
cbo.Items.Clear();
cbo.DataSource = cbos;
cbo.DataSource = cbos;
cbo.DisplayMember = "Title";
cbo.DisplayMember = "标题";
cbo.ValueMember = "Value";
cbo.ValueMember = "价值";
回答by TheBlastOne
cbo.DataSource = null;
cbo.DataSource = cbos;
cbo.DisplayMember = "Title";
cbo.ValueMember = "Value";
Now before setting cbo.SelectedValue
, or relying on Items
to be up-to-date, call
现在在设置之前cbo.SelectedValue
,或者依赖于Items
最新,调用
cbo.CreateControl ;
and Items
will be re-calculated.
并将Items
重新计算。
The problem is that SelectedValue
/SelectedIndex
, which are WinForms properties, only accept the values that are legal according to the Items
list, but that one is built only after GUI interaction, i.e. after instantiating a "real" Windows GUI combo box, i.e. after obtaining a Windows handle for the combobox.
问题是SelectedValue
/ SelectedIndex
,它们是 WinForms 属性,只接受根据Items
列表合法的值,但只有在 GUI 交互之后构建,即在实例化一个“真实的”Windows GUI 组合框之后,即在获得一个 Windows 之后组合框的句柄。
CreateControl
forces the creation of the Windows handle, no matter what.
CreateControl
无论如何都强制创建 Windows 句柄。