问题 文本框自动完成(多行)


我在C#中制作了一个自动建议/完整文本框,我按照下面的链接,但文本框没有显示建议

如何在Windows窗体中创建自动提示文本框?

//-------- Get all distinct description -----------------------------
OleDbCommand command = new OleDbCommand(Queries.qry16, Connection);
OleDbDataReader reader = command.ExecuteReader();

//--------- Storing ------------------------------------
while (reader.Read())
{
    namesCollection.Add(reader.GetValue(0).ToString());
}

//----------- Close after use ---------------------------------------
reader.Close();

//----------- Set the auto suggestion in description box ------------
descriptionBox.AutoCompleteMode = AutoCompleteMode.Suggest;
descriptionBox.AutoCompleteSource = AutoCompleteSource.CustomSource;
descriptionBox.AutoCompleteCustomSource = namesCollection;

这是我的代码,它是winform的加载函数。 nameCollection初始化在构造函数中...请帮助使其正常工作。

我正在编辑我的帖子而不是创建新的...我已经在单行文本框中尝试了我自己的代码并且它有效。现在我想在多行中使用相同的...对于研究我用谷歌搜索了不同的代码(一个具有智能感),但它没有在文本框中提供自动建议。任何人都可以给我建议将整个程序编码为多行..谢谢。


11944
2017-10-19 10:55


起源

你确定了吗? namesCollection 实际上,当您将其指定为数据源时,它包含任何条目? - waldrumpus
private AutoCompleteStringCollection namesCollection;这就是我用于收集名称的内容 - greatmajestics
其实我发现了问题,它是文本框是多行而不是单行 - greatmajestics


答案:


AutoCompleteSource不适用于多行TextBox控件。

这意味着你需要从头开始:

我会创建一个ListBox来显示自动完成的内容:

var listBox = new ListBox();
Controls.Add(listBox);

你需要对你的文本框进行事件处理,但这有点粗糙,所以我会重写它以在某些时候停止keyupevent:

private void textBox_KeyUp(object sender, KeyEventArgs e)
{
    var x = textBox.Left;
    var y = textBox.Top + textBox.Height;
    var width = textBox.Width + 20;
    const int height = 40;

    listBox.SetBounds(x, y, width, height );
    listBox.KeyDown += listBox_SelectedIndexChanged;

    List<string> localList = list.Where(z => z.StartsWith(textBox.Text)).ToList();
    if(localList.Any() && !string.IsNullOrEmpty(textBox.Text))
    {
        listBox.DataSource = localList;
        listBox.Show();
        listBox.Focus();

    }
}

现在您只需要一个处理程序来设置textBox中的文本:

 void listBox_SelectedIndexChanged(object sender, KeyEventArgs e)
    {
        if(e.KeyValue == (decimal) Keys.Enter)
        {
            textBox2.Text = ((ListBox)sender).SelectedItem.ToString();
            listBox.Hide();                
        }
    }

在适当的地方进行空检查


11
2017-11-06 12:54



忘了提到这里的列表是你的自定义自动完成源。在这种情况下,它只是一个List <string>。 - helgeheldre
谢谢,由于我的帐户被暂停,我无法对所有答案表示感谢。 - greatmajestics
list和textBox2未定义 - Leo Gurdian
我将“var”添加到列表的init中。至于textBox2,这是winforms,所以它存在于另一个文件中,这个文件似乎相当多余,并且4年没有被遗漏。 - helgeheldre


您需要通过“添加新项”添加“新建组件”类。然后编写该类的代码,然后在需要的地方添加该组件。


2
2017-11-05 10:44



发给我你的电子邮件ID,我会发给你代码.. - Rahul Ranjan
感谢您的帮助。 - greatmajestics


尝试使用此代码,因为它适用于我的情况:

  AutoCompleteStringCollection MyCollection = new AutoCompleteStringCollection();
                while (reader.Read())
                {
                    namesCollection.Add(reader.GetString(0));
                }
                reader.Close();
    descriptionBox.AutoCompleteMode = AutoCompleteMode.Suggest;
descriptionBox.AutoCompleteSource = AutoCompleteSource.CustomSource;    
                descriptionBox.AutoCompleteCustomSource = namesCollection;
                con.Close();

请检查读者是否获得了所需的记录.. :)


1
2017-10-19 11:28



实际上我的代码工作后我把它改成单行......我仍然想知道如何将它用于多行 - greatmajestics
@GreatMajestics:阅读此链接。希望这能解决您的好奇心。:=) codeproject.com/Articles/5839/DIY-Intellisense - Rahul Ranjan
我已经检查了以下链接。在我的编辑中也提到过。但是没有得到如何实现我自己的建议文本框。 - greatmajestics


对“自动建议”的一点混淆,因为这基本上是自动完成的,没有用户的许可来“完成”文本。不过,这里有一些您可能会发现有用的链接:

http://docs.jquery.com/UI/Autocomplete

textarea上的自动完成功能

自动完成多行文本框的扩展程序

向下滚动链接#2,用户建议使用jquery解决方案并与链接#1进行比较。您可以找到解决方案。

第三个链接来自asp论坛,像你这样的类似问题也通过链接回答。你可能想检查一下。


0
2017-11-10 14:55





这可以帮助你解决问题; 您可以更改表名称。您可以将查询更改为加载列表框。

    ListBox lbox;
    private void IletisimBilgileriDoldur()
    {
        try
        {
            string strQuery= "Select adres From tblIletisimBilgileri Where adres <> '';";
            veri = new OleDbCommand(strQuery,strConn);
            veri.CommandType = CommandType.Text;
            if (strConn.State == ConnectionState.Closed) strConn.Open();
            oku = veri.ExecuteReader();
            DataTable dt = new DataTable();
            dt.Load(oku);
            oku.Close();
            txtAdres.AutoCompleteCustomSource.Clear();
            if (dt.Rows.Count >= 0)
            {
                lbox = new ListBox();
                for (int count = 0; count < dt.Rows.Count; count++)
                {
                    lbox.Items.Add(dt.Rows[count]["adres"].ToString());
                }
            }
            txtAdres.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
            txtAdres.AutoCompleteSource = AutoCompleteSource.CustomSource;
            if (strConn.State == ConnectionState.Open) strConn.Close();
        }
        catch (Exception)
        {
            if (strConn.State == ConnectionState.Open) strConn.Close();
        }
    }

    private void txtAdres_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
    {
        var x = txtAdres.Left;
        var y = txtAdres.Top + txtAdres.Height;
        var width = txtAdres.Width;
        const int height = 120;

        lbox.SetBounds(x, y, width, height);
        lbox.KeyDown += lbox_SelectedIndexChanged;
        lbox.DoubleClick += lbox_DoubleClick;
        gbxAdres.Controls.Add(lbox);
        lbox.BringToFront();
        lbox.Show();
        ActiveControl = txtAdres;
    }

    void lbox_DoubleClick(object sender, EventArgs e)
    {
        txtAdres.Text = ((ListBox)sender).SelectedItem.ToString();
        lbox.Hide();
    }

0
2017-10-12 10:34