Userform with a selection of controls including a combobox. The combobox list is made up of a list of strings in the format 'nnnnnn SomeTextGoesHere', i.e. '123456 Test'.
The scenario is that the user copies '123456' from another source and pastes it into the combobox where it immediately finds a match, but to enable the 'project type' controls on the form, you either have to tab or enter to commit the selection:
I think I know the answer (No) but is there a way to commit on the partial match without having to press Tab or Enter?
One approach you could experiment with uses a watchdog timer that fires after some preset "idle" latency after the last text change expires. This particular code then detects two conditions that will trigger an auto-select:
1 - If the text that is pasted or entered, e.g. "123456", is contained by a single item in the list, select that unique item. (This option is more forgiving and would locate a match if, for example, "345" was typed in.)
2 - Alternatively, if a unique item starts with the pasted or entered text then trigger an auto select.
The watchdog timer prevents an instantaneous auto select while the user is "still typing".
For purposes of test, populate a combo box with these values.
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
comboBox.AutoCompleteSource = AutoCompleteSource.ListItems;
comboBox.TextChanged += (sender, e) =>
{
_wdt.StartOrRestart(action: () =>
{
if (!string.IsNullOrWhiteSpace(comboBox.Text))
{
// Condition 1: Applying "Contains" produces a unique result
object[] suggestions =
comboBox
.Items
.OfType<object>()
.Where(_ => $"{_}".Contains(comboBox.Text, StringComparison.OrdinalIgnoreCase))
.ToArray();
// Condition 2: "Starts With" produces a unique result
if (suggestions.Length == 1)
{
comboBox.SelectedIndex = comboBox.Items.IndexOf(suggestions[0]);
return;
}
suggestions =
comboBox
.Items
.OfType<object>()
.Where(_ => $"{_}".IndexOf(comboBox.Text, StringComparison.OrdinalIgnoreCase) ==0)
.ToArray();
if(suggestions.Length == 1)
{
comboBox.SelectedIndex = comboBox.Items.IndexOf(suggestions[0]);
}
}
});
};
}
// "Any" Watchdog timer.
// For example install NuGet: IVSoftware.Portable.WatchdogTimer
WatchdogTimer _wdt = new WatchdogTimer { Interval = TimeSpan.FromSeconds(0.5) };
}
First, test it with "123456" which is unique by either metric. It would also work to use "6 Test" for example.
"Test" is an ambiguous result by condition 1, but a unique result when if falls though to condition 2.