0

我试图在 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;
    }

谢谢,

4

1 回答 1

0

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

于 2013-11-09T04:30:04.893 回答