C#将过滤器添加到组合框下拉列表

在向我的ComboBox下拉列表添加过滤器时需要一些帮助(Windows Forms Visual Studio 2015)

下拉列表如下所示:

public ReconciliationReport()
{
    InitializeComponent();
    AppDomain.CurrentDomain.AssemblyResolve += FindDLL;

    this.sRootDirectory = Properties.Resources.sRootDirectory;

    string[] arrProjectList = Directory.GetDirectories(sRootDirectory).Select(Directory => Path.GetFileName(Directory)).ToArray();
    Array.Sort(arrProjectList);

    int iProjectCount = arrProjectList.Length;
    this.DropDownListSize = iProjectCount;

    for (int i = 0; i < iProjectCount; i++)
    {
        SelectJobDropdown.Items.Add(arrProjectList[i]);
    }
}

这为我提供了一个不错的所有当前目录的下拉列表.
enter image description here

现在,我需要添加一个文件管理器以仅显示包含在ComboBoxitself中键入文本的项目,而不管下拉列表本身是否打开.

我已禁用AutoCompleteMode和AutoCompleteSource,因为打开的下拉列表无法按预期运行.它是在现有列表的顶部打开附加列表,但是我只能从其下面的下拉列表中进行选择.请参阅下面的打印屏幕:
enter image description here

顶部的列表处于非活动状态,我无法选择文本,但是也没有显示子字符串的选项.

盒子本身只有一个

private void SelectJobDropdown_SelectedIndexChanged(object sender, EventArgs e) 
{
    //Plenty of code here 
}

当我在框内输入内容时,有人可以指出正确的方向如何过滤列表.

请注意,我仅使用C#三个星期,因此可能会与该语言的某些术语或其他方面混淆.

最佳答案
我建议使用2个列表.原始值1

List<string> arrProjectList;

public ReconciliationReport()
{
    InitializeComponent();
    AppDomain.CurrentDomain.AssemblyResolve += FindDLL;

    this.sRootDirectory = Properties.Resources.sRootDirectory;

    arrProjectList = Directory.GetDirectories(sRootDirectory).Select(Directory => Path.GetFileName(Directory)).ToList();
    arrProjectList.Sort();

    // then just bind it to the DataSource of the ComboBox
    SelectJobDropdown.DataSource = arrProjectList;
    // don't select automatically the first item
    SelectJobDropdown.SelectedIndex = -1;
}

和1表示过滤后的值.在此示例中,我使用TextBox捕获过滤器文本.在TextChanged事件中,获取过滤器文本并仅从原始arrProjectList列表中拉出那些值.如果过滤器为空,则最后需要一个额外的选项来将绑定重置为旧列表.

private void textBox1_TextChanged(object sender, EventArgs e)
{
    string filter_param = textBox1.Text;

    List<string> filteredItems = arrProjectList.FindAll(x => x.Contains(filter_param));
    // another variant for filtering using StartsWith:
    // List<string> filteredItems = arrProjectList.FindAll(x => x.StartsWith(filter_param));

    comboBox1.DataSource = filteredItems;

    // if all values removed, bind the original full list again
    if (String.IsNullOrWhiteSpace(textBox1.Text))
    {
        comboBox1.DataSource = arrProjectList;
    }

    // this line will make sure, that the ComboBox opens itself to show the filtered results       
}

编辑

我找到了一种将过滤器直接输入ComboBox的解决方案.过滤是相同的过程,但是使用TextUpdate事件,有必要取消选择SelectedIndex,它将自动设置为绑定之后的第一个元素.然后,我猜您想继续编写过滤器(不止一个字母),将过滤器写回到ComboBox.Text属性中,并将光标位置设置为末尾:

private void comboBox1_TextUpdate(object sender, EventArgs e)
{
    string filter_param = comboBox1.Text;

    List<string> filteredItems = arrProjectList.FindAll(x => x.Contains(filter_param));
    // another variant for filtering using StartsWith:
    // List<string> filteredItems = arrProjectList.FindAll(x => x.StartsWith(filter_param));

    comboBox1.DataSource = filteredItems;

    if (String.IsNullOrWhiteSpace(filter_param))
    {
        comboBox1.DataSource = arrProjectList;
    }
    comboBox1.DroppedDown = true;

    // this will ensure that the drop down is as long as the list
    comboBox1.IntegralHeight = true;

    // remove automatically selected first item
    comboBox1.SelectedIndex = -1;

    comboBox1.Text = filter_param;

    // set the position of the cursor
    comboBox1.SelectionStart = filter_param.Length;
    comboBox1.SelectionLength = 0;            
}

Etvoilà自动过滤,随后显示漂亮的箭头.

编辑2

对于不区分大小写的搜索,可以使用以下命令:

List<string> filteredItems = arrProjectList.FindAll(x => x.ToLower().Contains(filter_param.ToLower()));

注意:

打开下拉列表后为cursor will disappear.为防止这种情况,必须将Cursor.Current设置为Cursor.Defualt

comboBox1.DroppedDown = true;
Cursor.Current = Cursors.Default;

转载注明原文:C#将过滤器添加到组合框下拉列表 - 代码日志