ComboBox.Text does not respect ItemStringFormat property

I just noticed some strange behavior that 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>

      

ComboBox

displays values ​​as "## Foo ##", "## Bar ##" and "## Baz ##". But it TextBlock

displays the selected values ​​as "Foo", "Bar" and "Baz". So it ItemStringFormat

seems to be ignored for property Text

...

This is mistake? If so, is there a workaround?
Or am I just doing something wrong?

+2


a source to share


2 answers


This is not an error: ItemStringFormat

- it is just a shortcut to "data template where the text block is bound to a value with the specified string format set in the binding". Text

however, it is usually used when it IsEditable

is true and represents user input. If the list contains anything other than strings, it is preferable to use SelectedItem

than Text

. In any case, the following code will reapply the format to the text:



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

      

+1


a source


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

The solution I would use for the real problem that the OP mentioned in a comment to another answer is to use IValueConverter

.

Here's the code for the class FormatConverter

:

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 this is 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 will cause items to appear ComboBox

as "## Foo ##", "## Bar ##" and "## Baz ##" thanks to the ItemStringFormat

"## {0} ##" setting . Also, the property VMProp

on the ViewModel will be assigned values ​​in the same format when selected, thanks FormatConverter

when the parameter is ConverterParameter

set to "## {0} ##".

Note that even if I used the property ComboBox.Text

to stay consistent with the original question, I would assume that the property ComboBox.SelectedItem

would be more appropriate.;)

0


a source







All Articles