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

Tom*_*Tom 1 c# combobox filter dropdownbox winforms

在将过滤器添加到我的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]);
    }
}
Run Code Online (Sandbox Code Playgroud)

这为我提供了一个不错的所有当前目录的下拉列表。 在此处输入图片说明

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

我已经禁用了这两个功能,AutoCompleteMode并且AutoCompleteSource由于打开的下拉列表无法正常工作。它是在现有列表的顶部打开附加列表,但是我只能从其下面的下拉列表中进行选择。请参阅下面的打印屏幕: 在此处输入图片说明

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

盒子本身只有一个

private void SelectJobDropdown_SelectedIndexChanged(object sender, EventArgs e) 
{
    //Plenty of code here 
}
Run Code Online (Sandbox Code Playgroud)

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

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

Mon*_*Zhu 8

我建议使用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;
}
Run Code Online (Sandbox Code Playgroud)

和1表示过滤后的值。在此示例中,我使用a 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       
}
Run Code Online (Sandbox Code Playgroud)

编辑

我找到了一种将过滤器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;            
}
Run Code Online (Sandbox Code Playgroud)

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

编辑2

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

List<string> filteredItems = arrProjectList.FindAll(x => x.ToLower().Contains(filter_param.ToLower()));
Run Code Online (Sandbox Code Playgroud)

注意:

打开下拉列表后,光标将消失。为了防止这种情况,Cursor.Current必须将其设置为Cursor.Defualt

comboBox1.DroppedDown = true;
Cursor.Current = Cursors.Default;
Run Code Online (Sandbox Code Playgroud)