Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding ComboBox Text property using a converter

I'm having troubles using a WPF ComboBox in the following scenario:

ViewModel

  • Provides a ObservableCollection<T>; This collection contains a list of items the user may select.

  • Provides a property of type T representing the selected item.

The user shall be able to select either an existing item from the items in the ObservableCollection<T> or add a new item by typing in the string representation.

I have a converter available able to convert a item of type T to string and vice versa.

View

My ComboBox bound to the collection and the selected item properties:

<ComboBox ItemsSource="{Binding Path=MyObservableCollection}"
          SelectedItem="{Binding Path=MySelectedItem}"
          IsReadOnly="False" IsEditable="True"/>

The data template used to display the items correctly:

<DataTemplate DataType="{x:Type T}">
    <TextBlock Text="{Binding Converter={StaticResource ResourceKey=MyConverter}}"/>
</DataTemplate>

The Problem

Items in the drop down list of the ComboBox are displayed correctly using the convert. The selected item displayed in the TextBox of the ComboBox is not displayed correctly; Instead of using my converter, the ToString method is used.

Is it possible to specify a converter for the Text property? I tried using the following code:

<ComboBox ItemsSource="{Binding Path=MyObservableCollection}"
          SelectedItem="{Binding Path=MySelectedItem}"
          Text="{Binding Path=MySelectedItem, Converter={StaticResource ResourceKey=MyConverter}}"
          IsReadOnly="False" IsEditable="True"/>

This solves the display problem but now I get the Type.FullName of T in the converters ConvertBack method - which can of course not be converted.

Summary

I want the user to be able to select an item from a collection, allowing him to add new items by entering the string representation. The items in the collection shall be converted between string and object representation using a converter. The conversion shall be done in both the drop down list and the text box of the ComboBox.

Edit

Here is the code in my converter - no magic there just straightforward conversion:

public class MyConverter : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return MyConverter.Convert(value as T);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return MyConverter.Convert(value as string);
    }

    public static string Convert(T key)
    {
        // Conversion from T to string.
    }

    public static T Convert(string key)
    {
        // Conversion from string to T.
    }

}

Ok, now I found something that does what I want:

        <TextBox Text="{Binding Path=MySelectedItem, Converter={StaticResource ResourceKey=MyConverter}}"/>
        <ListBox ItemsSource="{Binding Path=MyObservableCollection}"
                 SelectedItem="{Binding Path=MySelectedItem, Converter={StaticResource ResourceKey=MyConverter}}"/>

This does exactly what I want; I can select predefined values and the user may add values on his own. Is it possible to do this with a ComboBox?

like image 544
Korexio Avatar asked Dec 04 '25 21:12

Korexio


1 Answers

In case someone facing same issue and don't want to cope with having a string property to bound to.

You can use the following

<ComboBox 
      ItemsSource="{Binding Path=MyObservableCollection}"
      Text="{Binding MySelectedItem, Converter={StaticResource DisplayConverter}}"
      SelectedValue="{Binding MySelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"                  
      >
<ComboBox.ItemTemplate>
    <DataTemplate>
        <TextBlock Text="{Binding Converter={StaticResource DisplayConverter}}"/>
    </DataTemplate>
</ComboBox.ItemTemplate>

Notice the binding is done on the SelectedValue, not SelectedItem. Then the display converter is added both to the Text & Itemtemplate properties.

  • On the Text property it will be used to convert the selected item display value.
  • On the ItemTemplate, to convert display values within the list box

I even use this snippet with Enum collection coming from ObjectDataProvider defined in the xaml. My enums have DisplayString attribute and combobox behave just fine to display the string value representation of the enums.

HTH

like image 156
Seb T. Avatar answered Dec 08 '25 18:12

Seb T.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!