【问题标题】:Implement a c# windows forms Autocomplete textbox with multiple suggested columns实现具有多个建议列的 c# windows 窗体自动完成文本框
【发布时间】:2013-11-09 04:22:41
【问题描述】:

我正在尝试在 C# 中实现一个类似于文本框的 Windows 窗体控件。当用户键入 3 个或更多字符时,将对数据源执行搜索。将返回多个字段(请参阅下面的类结构作为一种可能的定义)。

public class MyStructure
{
    public int Value1 { get; set; }
    public string Value2 { get; set; }
    public string Value3 {get; set; }
}

我的要求是显示一个包含多列的自动完成列表(注意:这可以是一个字符串,其中包含列表中连接在一起的填充字段)。当用户键入所有字符、点击向下箭头选择一个项目或点击回车键时,文本框中的值将采用列表的 ValueMember(其中列表的 DisplayMember 将是整个数据源)。用户输入的不是向上或向下箭头或回车键的每次击键都会执行另一次搜索并刷新列表。

我已经看到如何在自动建议中实现具有单列的文本框,但找不到一个相对“简单”的示例来说明如何为多列执行此操作。控件应该是文本框还是组合框,其样式以某种方式类似于文本框(如果可能的话)还是用户控件?

监控击键的事件应该是 TextEntered 还是 KeyPress 事件?我是否可以在不影响输入内容的情况下重置 AutoCompleteStringCollection(在任何尝试中我都会丢失我的输入或我在输入中的位置)?

谁能提供如何在框架 4.0 或更高版本中执行此操作的示例或指向我的示例?

编辑 1: 经过大量搜索,我发现基本上我需要在 TextBox 上实现一个 ContextMenuStrip (用户控件下方的任何其他控件和其他控件都将重叠)。我的问题是我无法确定如何处理 Tab 和 Enter 等按键事件。另外,如果用户继续输入,我需要处理(在这种情况下,我想将焦点切换回文本框并添加键)。以下是我的代码:

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        ContextMenuStrip menuStrip;
        string szMenuItem = string.Empty;

        // This would actually be a call to a web service
        List<MStarDeal> deals = DealInfo.Where(i => i.Value1.StartsWith(textBox1.Text.ToUpper()) || i.Value2.StartsWith(textBox1.Text.ToUpper()) || i.Value3.StartsWith(textBox1.Text.ToUpper()))
            .Select(i => i).ToList();

        if (textBox1.Text.Length >= 3 && !bSelected)
        {
            menuStrip = new System.Windows.Forms.ContextMenuStrip();

            foreach (MStarDeal item in deals)
            {
                szMenuItem = item.Value1.PadRight(15) + item.Value2.PadRight(20) + item.Value3.PadRight(80);

                ToolStripItem tsItem = new ToolStripMenuItem();
                tsItem.Text = szMenuItem;
                tsItem.Name = item.Value1;
                tsItem.MouseUp += tsItem_MouseUp;
                menuStrip.Items.Add(tsItem);
            }

            textBox1.ContextMenuStrip = menuStrip;
            textBox1.ContextMenuStrip.Show(textBox1, new Point(0, 20));
        }
        else if (bSelected)
        {
            bSelected = false;
        }
    }

    void tsItem_MouseUp(object sender, EventArgs e)
    {
        bSelected = true;
        textBox1.Text = ((ToolStripMenuItem)sender).Name;
    }

谢谢,

【问题讨论】:

    标签: c# winforms autocomplete multiple-columns


    【解决方案1】:

    我想我理解你的问题。使用 TextChanged() 事件而不是 KeyPress 怎么样?至于列,如果您将 flowLayoutPanel 设置为以正确的方向流动并使其大小适合合并的两列的宽度,则它会呈现列。

    【讨论】:

    • 在本例中,如何将 flowlayoutpanel 链接到文本框,以便在文本框中输入信息链接到 flowlayoutpanel?在这种情况下,我是否应该不实现 autocompletestringcollection 和相关属性(即一切都在 TextChanged 事件之外完成)?如何防止文本框文本中的这个位置被擦除?
    • 那个,我不知道。不使用 autoCompleteSource 等属性可能更容易。为什么不在 TextChanged 事件中对数据源执行搜索 textBox1.Text 呢?然后,将您找到的任何匹配项作为标签控件添加到 flowlayoutPanel?它将按照您的意愿显示在列中。
    • 我会尝试的——尽管我认为我需要 KeyPress 事件。这样,每次按下一个键 - 都会评估该键。如果该键是箭头键,则焦点将切换到 flowlayoutpanel 以向上或向下移动。将添加一个事件来设置文本框文本并切换焦点。我明天会尝试并发布答案。
    猜你喜欢
    • 2019-08-05
    • 1970-01-01
    • 2020-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-11
    • 2012-05-21
    • 2018-12-12
    相关资源
    最近更新 更多