2010-11-16 6 views
0

Je suis en train de créer une application de formulaire simple avec un dataGrid, un TextBox. J'ai environ 10K enregistrements de noms. Ce que je veux faire est d'implémenter une sorte de fonction d'achèvement automatique de sorte que lorsqu'un utilisateur tape dans la zone de texte, la grille de données est mise à jour pour afficher les correspondances en conséquence.Zone de texte Auto-complétée - Winform + LINQ

Juste pour tester ceci, j'ai un objet DataContext qui retourne les noms table et je mets un peu de code en cas textBox1_TextChanged pour réinitialiser la source de données avec

this.dataGrid1.DataSource = (from p in connectionWrapper.getConnectionObj.PatientsNormalizeds where p.Name.Contains(textBox1.Text) select p).Take(30);

Cela fonctionne bien sur une connexion locale mais lorsque vous extrayez des données d'un serveur SQL distant, ceci est bien sûr trop lent, le typage devient lent et inacceptable pour les utilisateurs.

Je me demandais simplement si quelque chose pouvait être fait sans changer la conception. Je peux bien sûr charger la table entière dans une liste ou DataTable à form_loading et exécuter la recherche contre elle mais cela fera cesser le répondeur pendant 3 secondes environ ...

Ceci est probablement très simple pour la plupart des développeurs mais Je suis très nouveau.

Merci!

+0

En fait, vous devez d'abord sélectionner TOUS les noms contenant l'entrée de l'utilisateur dans le DB, et seulement après cela, vous prenez les 30 premiers résultats. Mais votre base de données a été totalement traitée! Vous devriez arrêter votre requête juste après que les 30 premiers résultats aient été trouvés. Je ne connais pas assez bien LINQ ou SQL pour répondre, mais la solution devrait être facile si vous le faites. –

+0

est p une chaîne ou est-il peupler un objet? Parfois, si vous renvoyez un certain nombre d'objets, cela ralentira considérablement votre temps de chargement car il doit remplir chaque objet. – Gage

+0

Il s'agit d'un objet mais rien de fantaisie, juste nom, dob, téléphone # etc etc – Rillanon

Répondre

1

Deux approches s'imposent. Le premier impliquerait de ne pas filtrer sur chaque touche, mais plutôt de chercher quand l'utilisateur a fait une pause, c'est-à-dire qu'il pense qu'il a suffisamment tapé et qu'il veut voir ce qu'il renvoie. Cela pourrait être fait en utilisant une minuterie où le délai est réinitialisé à chaque pression de touche.

L'utilisation d'un thread d'arrière-plan pour exécuter la requête laisse l'interface sensible pendant que les données sont extraites.

Je chercherais aussi à renvoyer l'objet minimum de la LINQ, c'est-à-dire juste p.Name plutôt que l'objet p entier. Cela permettra également d'accélérer la transmission des données et la réactivité.

+0

Cela peut être facilement mis en œuvre en utilisant Reactive Extensions. – Giorgi

+0

@Giorgi, cela ressemble à une réponse. Vous devriez le poster comme tel. – Lazarus

+0

Merci!Cela me donne de bonnes idées. – Rillanon

0

Vous devez exécuter la sélection sur un thread d'arrière-plan aka BackgroundWorker

0

Vous pouvez mettre en cache des données localement dans un fichier XML ou quelque chose. L'application peut ne pas répondre pour la première fois (à moins que vous ne préchargiez les données en arrière-plan en utilisant des threads), mais ce sera vraiment rapide à chaque fois que vous lancerez l'application.
Vous pouvez implémenter un écran de préchargement/de démarrage pour informer les utilisateurs que les données sont chargées en arrière-plan.

1

Vous pouvez utiliser des extensions réactives pour implémenter facilement une solution qui interroge le serveur distant si l'utilisateur a tapé un certain nombre de symboles, mis en pause pendant un certain temps, très facilement. Les mains suivantes sur le laboratoire font exactement ceci: Rx .NET HOL

+0

+1 comme une excellente suggestion! – Lazarus

+0

J'ai pris le chemin de la facilité en changeant mon design pour aller chercher quand il est en pause et en utilisant un arrière-plan, maintenant le retard n'est pas évident pour l'utilisateur. – Rillanon

+0

L'utilisation de Rx donnerait-elle de meilleures performances? ou est-ce plus une amélioration axée sur le design. – Rillanon