Change Default Selection Logic

0 Answers 11 Views
MultiColumnComboBox
Shawn
Top achievements
Rank 1
Iron
Iron
Shawn asked on 27 Jun 2025, 06:01 PM

The data in all of our multi column combo boxes has a key value always as the first column in the grid. We want our users to be able to enter one of those key values then hit tab to select it. However, in some cases, just entering the key value doesn't cause the record with that key value to be at the top, so when the user hits tab it selects the top record instead of the record matching the key value entered.

See example below with US states as values:

 

In scenarios like these, I'd like to be able override the default selection logic and see if there is a record where the text in the search box exactly matches a key value, if so, select that value instead of the first value.

This was the last thing I tried inside the PreviewKeyDown event but it seemed to freeze and then not work as expected.

if (e.Key == System.Windows.Input.Key.Tab)
{
    string typedText = MultiColumnComboBox
        .FindChildByType<TextBox>()
        .Text
        .Trim();

    if (MultiColumnComboBox.DropDownContentManager.DropDownElement is RadGridView gridView)
    {
        string keyFieldName = gridView.Columns[0].UniqueName;

        var itemToSelect = gridView.Items
            .OfType<DataRow>()
            .FirstOrDefault(row =>
            {
                var keyValue = row[keyFieldName];
                return keyValue != null &&
                       keyValue.ToString().Equals(typedText, StringComparison.OrdinalIgnoreCase);
            });

        if (itemToSelect != null)
        {
            gridView.SelectedItem = itemToSelect;
        }
    }
}

Martin Ivanov
Telerik team
commented on 02 Jul 2025, 10:55 AM

I've tested your code and it doesn't freeze on my side, but indeed it doesn't work as intended. To fix this should delay the selection a bit.

private void RadMultiColumnComboBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Tab)
    {
        var mccb = (RadMultiColumnComboBox)sender;
        var text = mccb.AutoCompleteProvider.SearchText;

        var dt = (DataTable)mccb.ItemsSourceProvider.ItemsSource;
        var itemToSelect = dt.Rows.OfType<DataRow>()
            .FirstOrDefault(row => row["Id"] != null && row["Id"].ToString().Equals(text, StringComparison.OrdinalIgnoreCase));
        if (itemToSelect != null)
        {
            Dispatcher.BeginInvoke(new Action(() =>
            {
                mccb.SetCurrentValue(RadMultiColumnComboBox.SelectedItemProperty, itemToSelect);
            }));
        }
    }
}

You can see this in the attached project. I hope it helps.

Shawn
Top achievements
Rank 1
Iron
Iron
commented on 08 Jul 2025, 01:04 AM

It's half working now. As is, every time the user hits tab it runs that code, which means the user can never tab out of the field. So, if I make it so it only executes if the MultiColumnComboBox.SelectedItem is null, then it does override the selection and set the proper selected item the first time the user hits tab. But the second time the user hits tab (to attempt to leave the field it re-selects the first item in the grid again instead of moving to the next field.

 

Martin Ivanov
Telerik team
commented on 10 Jul 2025, 09:48 AM

To resolve this, you can extend the solution a bit and empty the CurrentItem of the associated RadGridView when the search text is empty. This will prevent part of the internal logic of RadMultiColumnComboBox from executing.

private void RadMultiColumnComboBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Tab)
    {
        var mccb = (RadMultiColumnComboBox)sender;
        var text = mccb.AutoCompleteProvider.SearchText;
        if (!string.IsNullOrEmpty(text))
        {
            // the custom selection logic here
        }
        else
        {
            var gridView = (RadGridView)mccb.DropDownContentManager.DropDownElement;
            gridView.CurrentItem = null;
        }
    }
}

No answers yet. Maybe you can help?

Tags
MultiColumnComboBox
Asked by
Shawn
Top achievements
Rank 1
Iron
Iron
Share this question
or