варианты:
- использовать Hacky решения
- использовать чистые C# автозаполнение управления (например, написать свой собственный или использовать чужой)
- switch to combobox
Вы можете найти № 2 и № 3 самостоятельно. Я считаю, что №2 - лучший вариант. Однако прочитайте, если вы хотите сделать # 1:
Чистое решение по тому, что вы просите, не существует. Мое понимание автозаполнения заключается в том, что это COM-объект, возможно, изначально построенный для Internet Explorer (поскольку в окне Spy ++ есть заголовок «Internet Explorer» в его иерархии). Во всяком случае, автозаполнение перехватывает события WndProc из элемента управления редактирования. Он заполняет и отображает список, когда он получает уведомления о событиях, таких как KEY_DOWN.
Например, предположим, что у вас есть автозаполнение с хотя бы одним словом, начинающимся с буквы «А». Вы можете заставить автозаполнение появляться, отправив сообщение POST в TextBox:
//host.Text = "A"; // does not work
PostMessage(textbox.Handle, WM_KEYDOWN, VK_A, 0); // works (see SendKey method below)
[DllImport("user32.dll")]
static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);
// only works once the Handle has been assigned
public void Show() {
ShowWindow(Handle, SW_SHOWNOACTIVATE);
}
// e.g. VK_A = 0x41, VK_SPACE = 20;
public void SendKey(int VK_KEY) {
PostMessage(Host.Handle, 0x100, VK_KEY, 0);
System.Threading.Tasks.Task.Run((Action) delegate {
Thread.Sleep(10); // small delay required
Host.BeginInvoke((Action) delegate {
Show();
});
});
}
Насколько я знаю, это не представляется возможным непосредственно контролировать содержание в автозаполнении. Тем не менее, в другом потоке stackoverflow (не удается найти его сейчас) ответ заключался в том, чтобы префикс каждого слова пробел, чтобы все они использовали общий префикс, а затем обрезали значение впоследствии.
Вы также можете заставить автозаполнение появляться без ввода чего-либо, но, к сожалению, оно будет пустым. Например:
const int SW_SHOWNOACTIVATE = 4;
IntPtr p = ...; // handle to Autocomplete window
int width = 400;
int height = 200;
SetWindowPos(p, IntPtr.Zero, -5, 0, width, height, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
ShowWindow(p, SW_SHOWNOACTIVATE);
Вы можете узнать, как получить ссылку ручки здесь: Combo box drop down width on suggest
Даже когда у вас есть ручки, нет никакой прямой или косвенной ссылки на его владеющий контроль редактирования. В приведенной выше гиперссылке единственный способ определить элемент управления редактированием - это прослушивать первый раз, когда отображается автозаполнение, а затем проверять каждый элемент управления, чтобы увидеть, какой элемент управления находится на экране.
Ничего себе. Появляется настолько хакерским для такого простого случая использования. Попробуй. – NLV
Я был уверен, что «PostMessage» работает, но похоже, что я что-то изменил в своем коде, и теперь он не работает. В любом случае, если он не работает, вы можете выполнить 'control.Focus(); SendKeys.Send (""); ' – Loathing
Кажется, что небольшая задержка, за которой следует' Show(), может решить проблему. Добавлен код, который работает для меня с помощью 'PostMessage'. – Loathing