我有一个绑定到DataSource的ComboBox。我想根据特定条件动态添加项目到ComboBox。所以我所做的是将选项添加到新列表,然后像这样更改ComboBox的DataSource:
cbo.DataSource = null;
cbo.DataSource = cbos;
cbo.DisplayMember = "Title";
cbo.ValueMember = "Value";
然后,我检查cbo.Items.Count
,它没有增加 - 它不等于DataSource的计数。我能在这做什么想法?注意这是WinForms而不是asp.net。
谢谢
答案 0 :(得分:12)
您是否立即或稍后检查了伯爵? ComboBox有可能实际上没有更新它的内容,直到有一个操作,如UI刷新,因此计数将关闭,直到那个时间。
如果在为ComboBox创建句柄之前更新DataSource,则可能发生这种情况。我在反射器上挖了一些代码,看起来在这种情况下不会更新项目,直到实际创建和渲染ComboBox。
答案 1 :(得分:6)
如果有人在动态添加的组合框中遇到此问题,答案是确保将组合框添加到表单中容器的控件。
添加“this.Controls.Add(cbo);”在设置数据源之前的代码中,问题就消失了。
答案 2 :(得分:5)
我找到了原因......
我取出了cbo.Datasource = null行..并在最后添加了一个cbo.Invalidate()。这解决了这个问题。
感谢大家的建议。
答案 3 :(得分:4)
cbo.DataSource = null;
cbo.DataSource = cbos;
cbo.DisplayMember = "Title";
cbo.ValueMember = "Value";
现在,在设置cbo.SelectedValue
或依赖Items
进行更新之前,请致电
cbo.CreateControl ;
和Items
将重新计算。
问题是SelectedValue
/ SelectedIndex
,它们是WinForms属性,只接受根据Items
列表合法的值,但是只有在GUI交互之后才构建一个,即在实例化“真正的”Windows GUI组合框之后,即在获得组合框的Windows句柄之后。
CreateControl
强制创建Windows句柄,无论如何。
答案 4 :(得分:1)
By adding "this.Controls.Add(cbo);" to the code before setting the datasource, the problem goes away.
//Create dynamic combobox and add to Panel
ComboBox ddCombo = new ComboBox();
controls = new Control[1] { ddCombo };
panel.Controls.AddRange(controls);
//After creating add to table layout
tableLayoutPanel.Controls.Add(panel, 0, 0);
ddCombo .Name = "ddName";
ddCombo .Width = 200;
ddCombo .Location = new Point(x, y); ddCombo .DataSource = ds;//or any List
ddCombo .SelectedIndex = ddCombo .Items.Count - 1;
答案 5 :(得分:0)
只是为了澄清你是否在调用count()方法 调用databind()方法后
答案 6 :(得分:0)
此代码在消息框中为我生成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<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;
}
}
}
}
答案 7 :(得分:0)
comboBox1.DataSource = somelist;
int c1 = comboBox1.DataSource.Count; //仍为零
BindingContext dummy = this.comboBox1.BindingContext; //现在强制更新!
int c2 = comboBox1.DataSource.Count; //现在它等于somelist.Count
答案 8 :(得分:0)
我遇到了同样的问题(我正在使用VS 2005)。
您需要做的是将DataSource设置为null,清除项目,重新分配数据源,显示和评估成员。
例如
cbo.DataSource = null;
cbo.Items.Clear();
cbo.DataSource = cbos;
cbo.DisplayMember =“Title”;
cbo.ValueMember =“Value”;
答案 9 :(得分:0)
旧线程,但我尝试了其中一些解决方案,以及挂起/恢复bindingcontext,绑定和重置绑定源,只是简单地重新加载表单。在我的.datasource设置时,没有人使用新绑定的数据更新我的控件(我的items.count为空,就像OP一样)。
然后我意识到我的组合框位于代码开头被删除的标签页上,后来重新添加(在我的数据绑定之后)。 之前没有发生绑定事件,直到重新添加标签页。
回想起来似乎很明显,但由于调用顺序和无法确定事情何时发生变化,在运行时很难检测到。
答案 10 :(得分:0)
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属性。
答案 11 :(得分:0)
尝试此代码。
cbo.BindingContext = new BindingContext();
cbo.DataSource = null;
cbo.DataSource = cbos;
cbo.DisplayMember = "Title";
cbo.ValueMember = "Value";
也许您的ComboBox的BindingContext为空。
答案 12 :(得分:-1)
您只需通过preformLayout()函数刷新UI;
示例:
comboBox1.performLayout();
问候 mohsen s
答案 13 :(得分:-1)
请试试这个:
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);
我认为你的问题就像我今天遇到的一样。