简体   繁体   English

数据库中Winform中的textchange事件上的动态自动完成文本框

[英]dynamic autocomplete textbox on textchange event in winform with database

how can achieve dynamic auto complete textbox in c# winform? 如何在c#winform中实现动态自动完成文本框?

for example ,in my application have a textbox named txtbox_mobileno. 例如,在我的应用程序中有一个名为txtbox_mobileno的文本框。 i wanna bind mobile number(from database table named customer) with txtbox_mobileno. 我想用txtbox_mobileno绑定手机号码(来自名为客户的数据库表)。 the table customer have more than 100,000 records .client want suggestion list while typing mobile number in application . 表客户有超过100,000条记录。客户在应用程序中输入手机号码时需要建议列表。

so i tried to implement following code on textchanged event 所以我试图在textchanged事件上实现以下代码

if (txtbox_mobileno.TextLength >3)
{

cmd.CommandText = "SELECT  TOP 20 MobileNo FROM Customer WHERE MobileNo LIKE'" + txtbox_mobileno.Text+"%'";
SqlDataReader dr;
dr = RunSqlReturnDR(cmd);//return value
 if (dr.HasRows)
 {
    while (dr.Read())
    {
   C.Add(dr[0].ToString()); //AutoCompleteStringCollection C = new AutoCompleteStringCollection();
     }
  }
 dr.Close();
 txtbox_mobileno.AutoCompleteMode = AutoCompleteMode.Suggest;
 txtbox_mobileno.AutoCompleteSource = AutoCompleteSource.CustomSource;
 txtbox_mobileno.AutoCompleteCustomSource = C;
}

i want to show the suggestion list only if text box have more than 3 letters when tried to bind on load event, it took around 5 minutes to bind data with textbox suggestion list , 我仅在尝试在加载事件上绑定时文本框具有3个以上字母的情况下才显示建议列表,用文本框建议列表将数据绑定到此大约需要5分钟,

Sql server query execution time was only 3 seconds. Sql server查询的执行时间仅为3秒。

is there any fastest way to overcome this issue? 有什么最快的方法可以解决此问题?

I am not sure if you are able to grab all mobile numbers at the beginning of your app or at least when your data entry form loads up, but if so, it may be easier to load all of the numbers into buckets with the first three characters being the key for the list of numbers. 我不确定您是否能够在应用程序的开头或至少在加载数据输入表单时抓取所有手机号码,但是如果这样,将前三个数字全部加载到存储桶中可能会更容易字符是数字列表的关键。 Even if you had 1,000,000 numbers, you are only talking around 30 MB of data (assuming I did my math correctly), so you shouldn't have any issues in that regard. 即使您有1,000,000个数字,您也只在谈论30 MB的数据(假设我正确地进行了数学运算),因此在这方面您应该没有任何问题。 You could do something like this to build your buckets. 您可以执行类似的操作来构建存储桶。 As an aside, I also have no idea how many numbers you get that have the same first three digits, so I may be building very large autocomplete lists in this code which would be another problem. 顺便说一句,我也不知道有多少个数字具有相同的前三位数字,因此我可能会在此代码中构建很大的自动完成列表,这将是另一个问题。 Your code only pulled back the top 20, you could modify this code to only keep the first 20 or something like that. 您的代码只拉回前20名,您可以修改此代码以仅保留前20名或类似内容。

var buckets = new Dictionary<string, List<string>>();
cmd.CommandText = "SELECT MobileNo FROM Customer";
SqlDataReader dr = RunSqlReturnDR(cmd);
if (dr.HasRows)
{
    while (dr.Read())
    {
        var number = dr[0].ToString();
        var key = number.Substring(0, 3);
        List<string> numbers = null;
        if(!buckets.TryGetValue(key, out numbers))
        {
            numbers = new List<string>();                 
        }
        numbers.Add(number);
    }
}
dr.Close();

Then in your event handler you just need to do something like this: 然后,在事件处理程序中,您只需要执行以下操作即可:

if (txtbox_mobileno.Text.Length == 3)
{
    List<string> numbers;
    if (_buckets.TryGetValue(txtbox_mobileno.Text, out numbers)
    {
        var ac = new AutoCompleteStringCollection();
        ac.AddRange(numbers.ToArray());
        txtbox_mobileno.AutoCompleteMode = AutoCompleteMode.Suggest;
        txtbox_mobileno.AutoCompleteSource = AutoCompleteSource.CustomSource;
        txtbox_mobileno.AutoCompleteCustomSource = ac;
    }
}

Other ways you could potentially enhance this would be to add an order by in the query where you get the numbers, then you should be able to walk the values and just create a new list when you hit a change in the first three digits. 可能会增强此功能的其他方法是在查询中添加数字的顺序,然后您应该能够遍历值并在遇到前三个数字的变化时仅创建一个新列表。 That would make it easier to build a dictionary of arrays rather than a dictionary of lists, which would then help in your autocomplete box. 这样可以更轻松地构建数组字典而不是列表字典,这将有助于自动完成框。 I also haven't written a lot of DB code in a while, so I just kept the code you posted for getting the data out of the database. 我也已经有一段时间没有写很多数据库代码了,所以我只是保留了您发布的用于从数据库中获取数据的代码。 It is possible that there may be better ways to read the data from the database. 可能有更好的方法从数据库读取数据。

Try use a timer to fire query, and a Thread to execute, see: 尝试使用计时器来触发查询,并使用一个线程来执行,请参阅:

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        timer1.Enabled = false;
        timer1.Enabled = true;
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        timer1.Enabled = false;

        string filter = txtbox_mobileno.Text;

        Thread t = new Thread(() => {

            cmd.CommandText = "SELECT  TOP 20 MobileNo FROM Customer WHERE MobileNo LIKE '" + filter + "%'";
            SqlDataReader dr;
            dr = RunSqlReturnDR(cmd);//return value
            if (dr.HasRows)
            {
                while (dr.Read())
                {
                    C.Add(dr[0].ToString()); //AutoCompleteStringCollection C = new AutoCompleteStringCollection();
                }
            }

            dr.Close();

            txtbox_mobileno.Invoke((MethodInvoker)delegate {
                txtbox_mobileno.AutoCompleteMode = AutoCompleteMode.Suggest;
                txtbox_mobileno.AutoCompleteSource = AutoCompleteSource.CustomSource;
                txtbox_mobileno.AutoCompleteCustomSource = C;
            });
        });


        t.Start();
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM