Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 如何异步获取文本框的自动完成数据?_.net_Winforms_Autocomplete - Fatal编程技术网

.net 如何异步获取文本框的自动完成数据?

.net 如何异步获取文本框的自动完成数据?,.net,winforms,autocomplete,.net,Winforms,Autocomplete,我们的WinForms应用程序延迟加载数据以自动完成文本框。这方面的伪代码如下所示 文本框中的用户类型 键入pause时,确定是否需要获取自动完成的数据 在工作线程中,联系服务器并获取数据 调用回UI线程 设置textBox.AutoCompleteCustomSource=fetchedAutoCompleteStringCollection 强制文本框下拉它的自动完成下拉列表 我目前在#6方面有问题。作为一个黑客,我做了以下工作来模拟一个可以工作的按键,但它并不是在所有情况下都能工作

我们的WinForms应用程序延迟加载数据以自动完成文本框。这方面的伪代码如下所示

  • 文本框中的用户类型
  • 键入pause时,确定是否需要获取自动完成的数据
  • 在工作线程中,联系服务器并获取数据
  • 调用回UI线程
  • 设置
    textBox.AutoCompleteCustomSource=fetchedAutoCompleteStringCollection
  • 强制文本框下拉它的自动完成下拉列表
  • 我目前在#6方面有问题。作为一个黑客,我做了以下工作来模拟一个可以工作的按键,但它并不是在所有情况下都能工作

         // This is a hack, but the only way that I have found to get the autocomplete
         // to drop down once the data is returned.
         textBox.SelectionStart = textBox.Text.Length;
         textBox.SelectionLength = 0;
         SendKeys.Send( " {BACKSPACE}" );
    
    一定有更好的办法。我不敢相信我是唯一一个异步获取自动完成数据的人。我应该怎么做


    编辑:可以接受Win32调用以导致自动完成下拉列表。如果必须的话,我不介意PinVok退出。

    通常,您会使用COM互操作并访问或接口。不幸的是,这些方法都没有强制自动完成下拉的方法


    您可能希望使用Spy++并查看在显示自动完成时发送到控件的windows消息。您可能会找到一条命令消息来激活它。当然,这是一个实现细节,但这可能是唯一的方法。

    我已经为一个只使用托管代码的文本框编写了一个异步自动完成类。希望能有帮助

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