2017-08-05 4 views
1

comment peut-on réaliser une zone de texte automatique complète dans C# winform? Par exemple, dans mon application, j'ai une zone de texte nommée txtbox_mobileno. je veux lier le numéro de mobile (de la table de base de données nommée client) avec txtbox_mobileno. le client de la table ont plus de 100.000 enregistrements .client veulent la liste de suggestions tout en tapant le numéro de mobile dans l'application.zone de texte de saisie semi-automatique dynamique sur l'événement textchange dans winform avec base de données

donc j'ai essayé de mettre en œuvre le code suivant sur événement 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; 
} 

je veux afficher la liste de suggestion que si zone de texte ont plus de 3 lettres quand essayé de lier le cas de charge, il a fallu environ 5 minutes pour lier les données avec la liste de suggestions de la zone de texte,

La durée d'exécution de la requête du serveur SQL était de seulement 3 secondes.

Y at-il un moyen plus rapide de résoudre ce problème?

+0

Les numéros de téléphone mobile dans la base de données changent-ils lorsque cette application est en cours d'exécution ou pouvez-vous considérer que cette liste de numéros est statique pendant le temps que cette zone de texte est affichée à l'écran? Je me demande si vous pourriez saisir les chiffres au lancement de l'application et les classer dans des compartiments en fonction des trois premiers chiffres. Ensuite, tout ce que vous avez à faire est de saisir le seau dans votre événement de texte modifié. – pstrjds

Répondre

-1

Essayez d'utiliser une minuterie pour tirer requête et un thread pour exécuter, voir:

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(); 
    } 
+0

Je ne suis pas sûr de savoir comment cela serait mieux? Voulez-vous vraiment lancer un thread exécutant une requête DB chaque fois que la zone de texte est modifiée? Certes, vous n'avez pas spécifié la durée de la minuterie, mais cela semble très compliqué et je ne suis pas convaincu qu'il y aurait un gain de performance. – pstrjds

+0

meilleure méthode est sql dépendance –

0

Je ne sais pas si vous êtes en mesure de saisir tous les numéros mobiles au début de votre application ou tout au moins lorsque votre formulaire d'entrée de données se charge, mais si c'est le cas, il peut être plus facile de charger tous les nombres dans des compartiments avec les trois premiers caractères étant la clé pour la liste des nombres. Même si vous aviez 1 000 000 de numéros, vous ne parlez que d'environ 30 Mo de données (en supposant que j'ai fait mes calculs correctement), donc vous ne devriez pas avoir de problèmes à cet égard. Vous pourriez faire quelque chose comme ça pour construire vos seaux. En outre, je n'ai aucune idée du nombre de numéros qui ont les mêmes trois premiers chiffres, donc je peux construire de très grandes listes de saisie semi-automatique dans ce code, ce qui serait un autre problème. Votre code n'a fait que reculer le top 20, vous pouvez modifier ce code pour ne conserver que les 20 premiers ou quelque chose comme ça.

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(); 

Ensuite, dans votre gestionnaire d'événements, vous avez juste besoin de faire quelque chose comme ceci:

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

D'autres façons dont vous pourriez potentiellement améliorer ce serait d'ajouter une commande par la requête où vous obtenez les numéros , alors vous devriez pouvoir marcher les valeurs et juste créer une nouvelle liste quand vous frappez un changement dans les trois premiers chiffres. Cela rendrait plus facile de construire un dictionnaire de tableaux plutôt qu'un dictionnaire de listes, ce qui aiderait dans votre boîte de saisie semi-automatique. Je n'ai pas écrit beaucoup de code DB depuis un moment, donc j'ai simplement gardé le code que vous avez posté pour extraire les données de la base de données. Il est possible qu'il existe de meilleurs moyens de lire les données de la base de données.

+0

essayé code donné mais son ne fonctionne pas bien, sur l'événement de changement de texte sa liste de suggestions ne fonctionne pas, et une chose, si quelqu'un ajoute un nouveau numéro de mobile en DB, comment obtenir le nouveau numéro de mobile? –

+0

@SafvanAP - Je n'ai pas testé le code, je l'ai simplement construit sur votre code, mais quand vous dites "ça ne marche pas bien", voulez-vous dire qu'il y a une erreur, la liste est vide, l'événement n'est pas tir, que voulez-vous dire que ça ne fonctionne pas? En ce qui concerne le nouveau numéro, cela faisait partie de la nature de ma question - cette liste est-elle considérée statique pendant l'exécution du programme? D'après ce que vous venez de demander, il semble que ce ne soit pas statique et que mon idée ne vous aiderait probablement pas. – pstrjds