C# ComboBox.Item.AddRange(string[])与ComboBox.DataSource=string[]

C# ComboBox.Item.AddRange(string[])与ComboBox.DataSource=string[],c#,winforms,performance,combobox,C#,Winforms,Performance,Combobox,因此,我有两个选择: aComboBox.Item.AddRange(stringArray); aComboBox.SelectedItem = stringFromStringArray; 及 现在,第一个是waaaaay,在初始化时会慢一些(大约5-6倍)。它确实正确地设置了所选项目,但仍然非常慢,所以我决定使用第二个项目 但是,如果使用第二个命令,则在执行第二个命令时,aComboBox中的项数组尚未设置,因此所选项是索引1处的项,而不是指定的项 问题是,如何利用第一个的功能获得第二个

因此,我有两个选择:

aComboBox.Item.AddRange(stringArray);
aComboBox.SelectedItem = stringFromStringArray;

现在,第一个是waaaaay,在初始化时会慢一些(大约5-6倍)。它确实正确地设置了所选项目,但仍然非常慢,所以我决定使用第二个项目

但是,如果使用第二个命令,则在执行第二个命令时,
aComboBox
中的项数组尚未设置,因此所选项是索引1处的项,而不是指定的项

问题是,如何利用第一个的功能获得第二个的性能

编辑:

使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用System.Windows.Forms;
名称空间组合框测试
{
类主窗口:窗体
{
字符串[]列表=新字符串[1548];
TableLayoutPanel=新建TableLayoutPanel();
公共主窗口():基()
{
高度=2000;
宽度=1000;
Random rand=新的Random();
对于(int i=0;i<1547;i++)
{
list[i]=rand.Next().ToString();
}
list[1547]=5.ToString();
按钮按钮=新按钮();
button.Text=“按我”;
按钮。单击+=按钮\u单击;
面板。控件。添加(按钮,0,0);
面板高度=2000;
面板宽度=1000;
控件。添加(面板);
Show();
}
私有无效按钮\u单击(对象发送者,事件参数e)
{
对于(int i=0;i<36;i++)
{
ComboBox=新的ComboBox();
box.DataSource=list;//box.Items.AddRange(list);
box.SelectedItem=5.ToString();
面板控件添加(框,0,i+1);
}
}
}
}
我重现了这个程序的问题。如果将其更改为
addRange()
,将花费更多的时间,但会设置项目

尝试向
SelectedItem
添加断点,然后查看
组合框。
如果设置一个,另一个将为空(
DataSource
vs.
Items
)。
组合框
似乎在查看
以检查列表中是否存在字符串,这就是使用
数据源
方法失败的原因


附加问题:为什么所有的组合框都作为一个(尝试更改值)?

使用数据源方法和FindString方法查找所需选定文本的索引:

string[] arrString = {"hello", "how r u", "fine" };
comboBox1.DataSource = arrString;
comboBox1.SelectedIndex=comboBox1.FindString("fine");
MessageBox.Show(comboBox1.SelectedIndex.ToString());
问题是,我如何获得第二个的性能 第一个的功能是什么

如果希望它正常工作,可以移动行
box.SelectedItem=5.ToString()添加到行

当您对组合框使用
DataSource
时,仅当表单上存在组合框时,设置
SelectedItem
才有效

我不确定性能,但确定功能

附加问题:为什么所有的组合框都作为一个工作(尝试更改) 价值是多少

因为它们绑定到相同的
数据源
。事实上,他们使用的是一个
BindingManagerBase


您可以为它们使用不同的
BindingSource
。您还可以将它们绑定到
list.ToList()

无法复制第二种情况。请将其作为一个独立的项目进行测试,并发布一个简单的复制代码。只需搜索这些项目,直到获得指定的项目,并使用10100100010000和100000个项目将所选索引设置为itI测试。它工作正常。它首先设置
数据源
,然后设置所选项目。可能您的
stringFromStringArray
在数组中不存在。stringFromStringArray在数组中存在,这是我检查的第一件事。由于
数据源
之间的关系,无法工作。索引也会失败。你所说的关系是什么意思?使用FindStringExactI我正在使用一个循环将36个复杂控件添加到
表格布局面板
,该面板位于选项卡中,也位于窗口中的选项卡中。如果我必须将对每个组合框的引用一直保留到窗口(窗体),代码将变得非常混乱和丑陋。有没有其他方法可以做到这一点,让它在它真正存在之前就认为它存在?我真的不想让代码过于复杂,另一种方法太慢了,会让人受伤……我没有说你应该将它们添加到表单中,你应该在它们添加到面板后设置
SelectedItem
。将它们添加到面板时,它们存在于窗体上。但是关于表现,我认为最好让你之前的问题得到答案:)是的,出于某种原因,这在我的主程序中不起作用。问题是我在创建之后添加了所有内容。那么ComboBox所在的面板是什么?我在打开ComboBox后将其添加到一个包含处理ComboBox的方法的方法中。所以comboBox直到我在层次结构中添加了几个方法之后才存在。而那个面板,它仍然不存在,当我完成创建后,我也必须将它添加到选项卡中。然后把那个标签换成另一个。等等,等等。有什么想法吗?也许你可以将面板添加到窗体中,使其不可见,并使组合框工作。那是胡说八道。如果你问我的话,这是一个糟糕的控制设计。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ComboBoxTest
{
class MainWindow : Form
{
    string[] list = new string[1548];
    TableLayoutPanel panel = new TableLayoutPanel();

    public MainWindow() : base()
    {
        Height = 2000;
        Width = 1000;

        Random rand = new Random();

        for (int i = 0; i < 1547; i++)
        {
            list[i] = rand.Next().ToString();
        }

        list[1547] = 5.ToString();

        Button button = new Button();
        button.Text = "Press me";
        button.Click += Button_Click;

        panel.Controls.Add(button, 0, 0);

        panel.Height = 2000;
        panel.Width = 1000;

        Controls.Add(panel);

        Show();
    }

    private void Button_Click(object sender, EventArgs e)
    {
        for (int i = 0; i < 36; i++)
        {
            ComboBox box = new ComboBox();
            box.DataSource = list;  //box.Items.AddRange(list);
            box.SelectedItem = 5.ToString();

            panel.Controls.Add(box, 0, i+1);
        }
    }
}
}
string[] arrString = {"hello", "how r u", "fine" };
comboBox1.DataSource = arrString;
comboBox1.SelectedIndex=comboBox1.FindString("fine");
MessageBox.Show(comboBox1.SelectedIndex.ToString());