C# 向组合框下拉列表添加过滤器 [英] C# Adding Filter to combobox dropdown list

查看:32
本文介绍了C# 向组合框下拉列表添加过滤器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

需要帮助将过滤器添加到我的 ComboBox 下拉列表(windows Forms Visual Studio 2015)

Need some help with adding filter to my ComboBox drop down list(windows Forms Visual studio 2015)

下拉列表按以下方式填充:

The drop down is populated as per below:

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]);
    }
}

这给了我一个很好的所有当前目录的下拉列表.

This gives me a nice drop down list of all current directories.

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

Now, I need to add a filer to show only items which contain a text typed into the ComboBoxitself regardless if the dropdown list itself is open or not.

我已禁用 AutoCompleteModeAutoCompleteSource 因为它在打开的下拉列表中没有按预期工作.它在现有列表的顶部打开附加列表,但我只能从它下面的下拉列表中进行选择.请参阅下面的打印屏幕:

I have disabled both AutoCompleteMode and AutoCompleteSource as it was not working as expected with the opened droped down list. It was opening additonal list on top the existing one but I could only select from the dropdown under it. See print screen below:

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

The list on top is inactive and I cannot select the text but also does not give an option to display substrings.

即使是盒子本身也只有一个

Only have one even for the box itself which is

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

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

Can someone point in the right direction how to filter the list as I type within the box itself.

请注意,我只使用了 3 周 C#,因此可能会与该语言的某些术语或其他方面等混淆.

Please NOTE I have been using C# for only 3 weeks so might get confused with some of the terminology or other aspects of this language etc.

推荐答案

我建议使用 2 个列表.1 为原始值

I would suggest to use 2 Lists. 1 for the original values

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 列表中提取那些值.如果过滤器为空,您将需要在最后一个额外的选项来重置旧列表的绑定.

and 1 for the filtered values. In this example I use a TextBox to catch the filter text. In the TextChanged event take the filter text and pull out only those values from the original arrProjectList List. You would need an extra option at the end to reset the binding to the old list if the filter is empty.

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 属性并将光标位置设置到末尾:

I found a Solution for typing the filter into the ComboBox directly. The filtering is the same procedure, but using the TextUpdate event it is necessary to unselect the SelectedIndex which is automatically set to the first element after the binding. Then I guess you want to proceed to write your filter (more than just one letter), write the filter back into the ComboBox.Text property and set the cursor position to the end:

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;            
}

等等,自动过滤,之后会有漂亮的显示和箭头选择.

Et voilà automatic filtering with a nice display and arrow selection afterwards.

编辑 2

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

for case insensitive search you can use this:

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

注意:

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

After the opening of the dropdownlist the cursor will disappear. To prevent this the Cursor.Current has to be set to Cursor.Defualt

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

这篇关于C# 向组合框下拉列表添加过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆