diff --git a/src/System.Windows.Forms/System/Windows/Forms/Controls/DataGridView/DataGridViewComboBoxCell.cs b/src/System.Windows.Forms/System/Windows/Forms/Controls/DataGridView/DataGridViewComboBoxCell.cs index db5dc3b9c68..50bf6deb173 100644 --- a/src/System.Windows.Forms/System/Windows/Forms/Controls/DataGridView/DataGridViewComboBoxCell.cs +++ b/src/System.Windows.Forms/System/Windows/Forms/Controls/DataGridView/DataGridViewComboBoxCell.cs @@ -1580,6 +1580,24 @@ private bool LookupValue(object? formattedValue, out object? value) object? item; if (DisplayMemberProperty is not null || ValueMemberProperty is not null) { + // When the cell is in edit mode, check the item the user actually selected first. + // A linear search through the data source would return the first item whose display + // property matches, which is wrong when multiple items share the same display text. + if (OwnsEditingComboBox(RowIndex)) + { + object? selectedItem = EditingComboBox.SelectedItem; + if (selectedItem is not null) + { + PropertyDescriptor displayProp = DisplayMemberProperty ?? ValueMemberProperty!; + object? selectedDisplayValue = displayProp.GetValue(selectedItem); + if (selectedDisplayValue is not null && selectedDisplayValue.Equals(formattedValue)) + { + value = GetItemValue(selectedItem); + return true; + } + } + } + // Now look up the item in the DataGridViewComboBoxCell datasource - this can be horribly inefficient // and it uses reflection which makes it expensive - ripe for optimization item = ItemFromComboBoxDataSource((DisplayMemberProperty ?? ValueMemberProperty)!, formattedValue);