Thomas Levesque
Thomas Levesque

Reputation: 292695

ComboBox.Text not taking the ItemStringFormat property into account

I just noticed a strange behavior which looks like a bug. Consider the following XAML :

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:sys="clr-namespace:System;assembly=mscorlib">
  <Page.Resources>
    <x:Array x:Key="data" Type="{x:Type sys:String}">
        <sys:String>Foo</sys:String>
        <sys:String>Bar</sys:String>
        <sys:String>Baz</sys:String>
    </x:Array>
  </Page.Resources>
  <StackPanel Orientation="Vertical">
      <Button>Boo</Button>
      <ComboBox Name="combo" ItemsSource="{Binding Source={StaticResource data}}" ItemStringFormat="##{0}##" />
      <TextBlock Text="{Binding Text, ElementName=combo}"/>
  </StackPanel>
</Page>

The ComboBox displays the values as "##Foo##", "##Bar##" and "##Baz##". But the TextBlock displays the selected values as "Foo", "Bar" and "Baz". So the ItemStringFormat is apparently ignored for the Text property...

Is that a bug ? If it is, is there a workaround ?
Or am I just doing something wrong ?

Upvotes: 3

Views: 7331

Answers (2)

CptRobby
CptRobby

Reputation: 1531

I know this is probably too late to help the OP, but just in case someone else stumbles across this...

The solution I would use to the real problem that the OP mentioned in the comment to the other answer is to use an IValueConverter.

Here's the code for the FormatConverter class:

public class FormatConverter : System.Windows.Data.IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        string format = parameter.ToString();
        return string.Format(format, value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

And here's how you use it (taken from the question with modification):

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:sys="clr-namespace:System;assembly=mscorlib"
  xmlns:local="clr-namespace:YourNamespace">
  <Page.Resources>
    <x:Array x:Key="data" Type="{x:Type sys:String}">
      <sys:String>Foo</sys:String>
      <sys:String>Bar</sys:String>
      <sys:String>Baz</sys:String>
    </x:Array>
    <local:FormatConverter x:Key="FormatConverter" />
  </Page.Resources>
  <StackPanel>
    <ComboBox ItemsSource="{Binding Source={StaticResource data}}" ItemStringFormat="##{0}##"
              Text="{Binding Path=VMProp, Mode=OneWayToSource, Converter={StaticResource FormatConverter}, ConverterParameter=##{0}##}" />
  </StackPanel>
</Page>

This would cause the items to show up in the ComboBox as "##Foo##", "##Bar##", and "##Baz##" thanks to the ItemStringFormat being set to "##{0}##". Plus the VMProp property on the ViewModel would be assigned the values in the same format when they are selected thanks to the FormatConverter with the ConverterParameter being set to "##{0}##".

Please note that even though I used the ComboBox.Text property to remain consistent with the original question, I would suggest that the ComboBox.SelectedItem property would be more appropriate. ;)

Upvotes: 0

Julien Lebosquain
Julien Lebosquain

Reputation: 41253

It's not a bug: ItemStringFormat is just a shortcut for "data template having a textblock bound to the value with the specified string format set in the binding". Text however is generally used when IsEditable is true and represents user-input. When you have anything other than strings in your list, it's preferable to use the SelectedItem than the Text. In any case, the following code will reapply the format to the text:

<TextBlock Text="{Binding ElementName=combo, Path=Text, StringFormat='##{0}##'}"/>

Upvotes: 2

Related Questions