2010-01-16 3 views
1

Existe-t-il un moyen d'obtenir une exécution automatique asynchrone dans une zone de texte WinFix ou une zone de liste déroulante? AJAX est très bien, et je serais étonné si le framework .NET n'a pas d'équivalent client lourd.Saisie semi-automatique asynchrone dans Winforms

Répondre

3

Il n'y a pas cette caractéristique de la boîte, mais il ne devrait pas être trop difficile à mettre en œuvre vous-même ... Gérer l'événement TextChanged, envoyez une demande de manière asynchrone pour obtenir les éléments correspondants, et changer le AutoCompleteSource lorsque vous obtenez le résultat. Vous avez juste besoin d'être prudent pour accéder aux composants de l'interface utilisateur sur le thread d'interface utilisateur, en utilisant la méthode Invoke (ou vous pouvez utiliser un BackgroundWorker et accéder à l'interface utilisateur en cas RunWorkerCompleted)

+0

wow, semble être une telle surveillance . – tster

0

Je sais que dans MFC vous pouvez utiliser SHAutoComplete et shell va le faire pour vous. Cependant, je ne suis pas sûr de la meilleure façon de le faire dans WinForms, mais cela devrait être possible. Pour plus d'informations, voir this question et this one.

0

J'ai écrit une classe de saisie semi-automatique async pour une zone de texte:

using System; 
using System.Windows.Forms; 
using System.Collections.Generic; 
using System.Text; 
using System.ComponentModel; 

namespace TextboxAutocomplete 
{ 
    public abstract class AutoCompleteSource 
    { 
     private TextBox mTextBox; 
     private AutoCompleteMode mAutoCompleteMode; 

     public AutoCompleteSource(TextBox textbox) : 
      this(textbox, AutoCompleteMode.Suggest) { } 

     public AutoCompleteSource(TextBox textbox, AutoCompleteMode mode) 
     { 
      if (textbox == null) 
       throw new ArgumentNullException("textbox"); 

      if (textbox.IsDisposed) 
       throw new ArgumentException("textbox"); 

      mTextBox = textbox; 
      mAutoCompleteMode = mode; 

      mTextBox.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.None; 

      BackgroundWorker autoCompleteLoader = new BackgroundWorker(); 
      autoCompleteLoader.DoWork += new DoWorkEventHandler(autoCompleteLoader_DoWork); 
      autoCompleteLoader.RunWorkerCompleted += new RunWorkerCompletedEventHandler(autoCompleteLoader_RunWorkerCompleted); 
      autoCompleteLoader.RunWorkerAsync(); 
     } 

     void autoCompleteLoader_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 
      AutoCompleteStringCollection collection = e.Result as AutoCompleteStringCollection; 
      if (collection == null) return; 

      if (mTextBox.InvokeRequired) 
      { 
       mTextBox.Invoke(new SetAutocompleteSource(DoSetAutoCompleteSource), new object[] { collection }); 
      } 
      else 
      { 
       DoSetAutoCompleteSource(collection); 
      } 
     } 

     protected void DoSetAutoCompleteSource(AutoCompleteStringCollection collection) 
     { 
      if (mTextBox.IsDisposed) return; 

      mTextBox.AutoCompleteMode = mAutoCompleteMode; 
      mTextBox.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.CustomSource; 
      mTextBox.AutoCompleteCustomSource = collection; 
     } 

     void autoCompleteLoader_DoWork(object sender, DoWorkEventArgs e) 
     { 
      List<string> autoCompleteItems = GetAutocompleteItems(); 
      if (autoCompleteItems == null) return; 
      AutoCompleteStringCollection collection = new AutoCompleteStringCollection(); 
      collection.AddRange(GetAutocompleteItems().ToArray()); 
      e.Result = collection; 
     } 

     protected abstract List<string> GetAutocompleteItems(); 
    } 

    internal delegate void SetAutocompleteSource(AutoCompleteStringCollection collection); 
} 

exemple d'implémentation:

using System; 
using System.Windows.Forms; 
using System.Collections.Generic; 
using System.Text; 

namespace TextboxAutocomplete 
{ 
    class MockAutoCompleteSource : AutoCompleteSource 
    { 
     public MockAutoCompleteSource(TextBox textbox) 
      : base(textbox) 
     { 

     } 

     protected override List<string> GetAutocompleteItems() 
     { 
      List<string> result = new List<string>(); 
      for (int i = 0; i < 2500; i++) 
      { 
       result.Add(Guid.NewGuid().ToString()); 
      } 

      return result; 
     } 
    } 
} 

Comment l'utiliser:

... 
TextBox myTextbox = new TextBox(); 
MockAutoCompleteSource autoComplete = 
     new MockAutoCompleteSource(myTextbox); 
... 
+0

Mais la saisie semi-automatique doit se produire de manière asynchrone lorsque le texte est modifié. Comment est-il accroché à l'événement text_changed? – NLV