我正在以编程方式创建一个组合框,如下所示:
var cbo = new ComboBox();
cbo.HandleCreated += (s, e) =>
{
cbo.DataSource = mylist;
};
当我执行上述操作时,组合框将显示列表中包含的项的两倍。但是,当我执行以下操作时,组合框将显示正确数量的项目:
var cbo = new ComboBox() {
DataSource = mylist
};
为什么会这样?
答案 0 :(得分:3)
此代码重复了该记录,因为在您对组合框进行初始化时,它将触发事件 HandleCreated ,该事件会将您的列表添加到组合框中。然后,在完成初始化之后,代码的执行将再次击中事件 HandleCreated ,因为执行该事件的第一个事件来自初始化,第二个事件来自运行时执行本身。>
var cbo = new ComboBox(); //initialization
//below this comment is the event
cbo.HandleCreated += (s, e) =>
{
cbo.DataSource = mylist;
};
P.S。
在C#WinForms中填充组合框有更好的方法。每个控件(组合框,文本框等)都有各自不同的事件。您可以先检查该事件,而不要创建活动。
答案 1 :(得分:1)
HandleCreated
仅加注一次。问题是另外一回事,这是因为OnHandleCreated
和数据绑定已在ComboBox
中实现。
ComboBox
的{{3}}方法是这样工作的:
HandleCreated
事件。 (请记住,IsHandleCreated
在这一点上是正确的。)Items
集合中的每个项目发送一个OnHandleCreated
将项目添加到本机组合框的本机消息。 这是设置DataSource
的工作方式:
DataSource
中的每个项目,它首先CB_ADDSTRING
将该项目收集到Items
,然后检查IsHandleCreated
是否为真,发送一个CB_ADDSTRING
将项目添加到本机组合框的本机消息。 因此,当您在DataSource
事件中设置HandleCreated
时,对于每个项目,它都会发送两次CB_ADDSTRING
本机消息。
这就是为什么您在下拉菜单中两次看到项目,同时Items.Count
显示正确计数的原因。此外,如果您单击其他项目(项目的最后一半),则会收到索引超出范围异常。
要解决此问题,可以使用以下任一视蛋白:
您可以使用HandleCreated
BeginInvoke
事件代码的执行。
作为另一种选择,您可以依赖VisibleChanged
事件。
选项1-HandleCreated + BeginInvoke
var mylist = Enumerable.Range(1, 5).ToList();
var myvalue = 2;
var cbo = new ComboBox();
cbo.HandleCreated += (obj, args) =>
{
BeginInvoke(new Action(() =>
{
cbo.DataSource = mylist;
cbo.SelectedIndex = mylist.IndexOf(myvalue);
}));
};
this.Controls.Add(cbo);
选项2-可见更改
var mylist = Enumerable.Range(1, 5).ToList();
var myvalue = 2;
var cbo = new ComboBox();
cbo.VisibleChanged+= (obj, args) =>
{
cbo.DataSource = mylist;
cbo.SelectedIndex = mylist.IndexOf(myvalue);
};
this.Controls.Add(cbo);