У меня есть winform с выпадающим списком. Этот комбинированный список содержит имена всех сотрудников и действует как адресная книга:
Пока все хорошо. Единственная проблема заключается в том, что в нашем активном каталоге есть смешанные фамилии и имена, и я не знаю фамилию каждого человека. Однако автоматическое предложение комбинированного списка всегда начинается с начала строки, поэтому я могу искать только по фамилии.
По этой причине я попытался реализовать что-то вроде нечеткого поиска.
Поисксамо по себе работает отлично:
Но с реализацией моего поиска я получаю очень странное поведение, но сначала моя реализация, так что вы знаете, кто яговорить о.
Form1.cs
using System.Collections.Generic;
using System.Data;
using System.Windows.Forms;
namespace TicketCreator
{
public partial class TicketCreator_UI : Form
{
DataTable AllNames = new DataTable();
List<(string name, string mail)> DomainSearchResult = new List<(string name, string mail)>();
List<string> GeneratedNames = new List<string>();
public TicketCreator_UI()
{
InitializeComponent();
FillDropDown();
}
private void User_dropdown_KeyPress(object sender, KeyPressEventArgs e)
{
//string text = user_dropdown.Text;
string name = $"{user_dropdown.Text}{e.KeyChar.ToString()}";//join previous text and new pressed char
DataRow[] rows = AllNames.Select($"UserName LIKE '%{name}%'");
DataTable filteredTable = AllNames.Clone();
foreach (DataRow r in rows)
filteredTable.ImportRow(r);
user_dropdown.DataSource = null;
user_dropdown.DataSource = filteredTable.DefaultView;
user_dropdown.DisplayMember = "UserName";
user_dropdown.SelectedIndex = -1;
//user_dropdown.Text = text;
}
private void FillDropDown()
{
// fill users combobox
DomainSearchResult = ADTools.ListUsers();
foreach ((string name, string mail) user in DomainSearchResult)
{
GeneratedNames.Add($"{user.name} <{user.mail}>");
}
AllNames.Columns.Add("UserName");
foreach (string row in GeneratedNames)
AllNames.Rows.Add(row);
user_dropdown.DataSource = GeneratedNames;
user_dropdown.Text = "";
}
}
}
Во-первых, вызывается FillDropDown()
, который вытащит пользователей из AD и вытолкнет их в комбинированный список за один раз.
После этого при нажатии клавиши выполняется нечеткий поиск и обновляется ComboBox.
Посмотрите на скриншот:
Отображается последняя введенная мною буква, но как только я набираю новую, она заменяется нановейший вход. В этом примере я до сих пор набрал «Джулиан».
Я попытался подделать это поведение, сначала получив текст ComboBox, затем обновив источник данных и, наконец, заново вставив текст:
private void User_dropdown_KeyPress(object sender, KeyPressEventArgs e)
{
string text = user_dropdown.Text; // Updated
string name = $"{user_dropdown.Text}{e.KeyChar.ToString()}";//join previous text and new pressed char
DataRow[] rows = AllNames.Select($"UserName LIKE '%{name}%'");
DataTable filteredTable = AllNames.Clone();
foreach (DataRow r in rows)
filteredTable.ImportRow(r);
user_dropdown.DataSource = null;
user_dropdown.DataSource = filteredTable.DefaultView;
user_dropdown.DisplayMember = "UserName";
user_dropdown.SelectedIndex = -1;
user_dropdown.Text = text; // Updated
}
Текст теперь остается внутри ComboBox, но отражается. Следующий пример обнаруживается, когда я набираю «Джулиан Бехтольд»:
Я подозреваю, что текстовый маркер переходит в начало ComboBox, когда источник данных изменяется, ноПользовательский интерфейс не обновляется сразу. Вы можете видеть маркер позади буквы 1 после того, как набрали букву:
Можно ли изменить / обойти это поведение?
С уважением,
Джулиан Бехтольд
РЕДАКТИРОВАТЬ:
Ориентация устанавливается слева направо