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="co开发者_如何学编程mbo" 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 ?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}##'}"/>
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. ;)
精彩评论