We have XAML:

<Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <ComboBox IsEditable="true" Grid.Row="1" Name="f_Combobox" StaysOpenOnEdit="True"> <ComboBox.Style> <Style TargetType="{x:Type ComboBox}"> <Style.Triggers> <Trigger Property="SelectedItem" Value="{x:Null}"> <Setter Property="Background" Value="#D7E3BC"/> </Trigger> </Style.Triggers> </Style> </ComboBox.Style> <ComboBox.ItemsSource> <x:Array xmlns:System="clr-namespace:System;assembly=mscorlib" Type="{x:Type System:String}"> <System:String>ABCDE</System:String> <System:String>ABCD</System:String> <System:String>ABC</System:String> <System:String>AB</System:String> <System:String>A</System:String> </x:Array> </ComboBox.ItemsSource> </ComboBox> <TextBlock Text="{Binding Path=SelectedItem, ElementName=f_Combobox}" Grid.Row="2"/> </Grid> 

and now the magic begins, select the ABC element in the ComboBox and remove one character from the end, the fill is white, i.e. ComboBox considers that the item is selected, and in the text of the ComboBox it says that AB selected, although the TextBlock indicates that the element ABCDE selected.

The result is:

We select one element, change the text to another, and in the SelectItem ComboBox we get the third element in general, and the user will not even know about it ... ( TextBlock is not in the project, it was created only for demonstration).

  • ... The question is what? - Ev_Hyper
  • The question is that the text in the combo box does not match the selected item. - Dmitry Chistik
  • somehow difficult to understand. Make it easier, override the ToString () method of your objects in the ComboBox and use without DisplayMemberPath - Gardes
  • hmm, in my comboBox ABCDE highlighted when editing. I suspect that when editing the value from the keyboard, it is not the closest value that is selected, but the first one found. Change of order to A - AB - ABC - ABCD - ABCDE confirms this - Andrey NOP
  • @Gardes made, it turns out with the usual strings the same chip. - Dmitry Chistik

1 answer 1

Add a Setter ComboBox style.

 <Setter Property="SelectedItem"> <Setter.Value> <MultiBinding Mode="OneWay"> <MultiBinding.Converter> <local:HelpConverter/> </MultiBinding.Converter> <Binding RelativeSource="{RelativeSource Self}" Path="ItemsSource"/> <Binding RelativeSource="{RelativeSource Self}" Path="Text" UpdateSourceTrigger="PropertyChanged"/> <Binding RelativeSource="{RelativeSource Self}" Path="DisplayMemberPath"/> </MultiBinding> </Setter.Value> </Setter> 

and describe the converter itself, which will also work with the DisplayMemberPath in ComboBox

 public class HelpConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { if (values.Length >= 2 && values[0] is IEnumerable && values[1] is string) { string displayString = null; if (values.Length >= 3 && values[2] is string) displayString = (string)values[2]; IEnumerable collection = (IEnumerable)values[0]; IEnumerator enumerator = collection.GetEnumerator(); string equalsText = (string)values[1]; while (enumerator.MoveNext()) { string elementDisplayString = null; if (string.IsNullOrWhiteSpace(displayString)) elementDisplayString = enumerator.Current?.ToString(); else { if (enumerator.Current != null) { System.Reflection.PropertyInfo p = enumerator.Current.GetType().GetProperty(displayString); if (p != null && p.CanRead) elementDisplayString = p.GetValue(enumerator.Current)?.ToString(); } } if (equalsText.Equals(elementDisplayString, StringComparison.InvariantCultureIgnoreCase)) return enumerator.Current; } } return null; } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotSupportedException(); } } 

If someone has found a more elegant solution, please reply, thanks.

  • Wow. I reproduced strange behavior, but did not know how to approach it. - VladD
  • @VladD And if you redefine styles, you will have to face the problem of merging styles, but there is an article on the stack on this ... - Dmitry Chistik