Асинхронное автозаполнение в winforms - PullRequest
1 голос
/ 17 января 2010

Есть ли способ получить асинхронное автозаполнение в Winforms TextBox или ComboBox? AJAX настолько хорош, и я был бы удивлен, если бы .NET Framework не имел толстого клиентского эквивалента.

Ответы [ 3 ]

3 голосов
/ 17 января 2010

Нет такой функции из коробки, но не должно быть слишком сложно реализовать ее самостоятельно ... Обработайте событие TextChanged, отправьте запрос асинхронно, чтобы получить соответствующие элементы, и измените AutoCompleteSource когда вы получите результат. Вам просто нужно быть осторожным, чтобы получить доступ к компонентам пользовательского интерфейса в потоке пользовательского интерфейса, используя метод Invoke (или вы можете использовать BackgroundWorker и получить доступ к пользовательскому интерфейсу в событии RunWorkerCompleted)

0 голосов
/ 01 декабря 2011

Я написал класс асинхронного автозаполнения для TextBox:

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

Пример реализации:

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

Как это использовать:

 ...
 TextBox myTextbox = new TextBox();
 MockAutoCompleteSource autoComplete =
      new MockAutoCompleteSource(myTextbox);
 ...
0 голосов
/ 18 января 2010

Я знаю, что в MFC вы можете использовать SHAutoComplete , и оболочка сделает это за вас. Однако я не уверен, что лучший способ сделать это в WinForms, но это должно быть возможно.

См. этот вопрос и этот вопрос для получения дополнительной информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...