ComboBox.Text没有考虑ItemStringFormat属性

时间:2010-05-17 08:02:59

标签: wpf xaml binding

我刚注意到一个奇怪的行为,看起来像个bug。请考虑以下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将值显示为“## Foo ##”,“## Bar ##”和“## Baz ##”。但TextBlock将所选值显示为“Foo”,“Bar”和“Baz”。因此ItemStringFormat属性显然忽略了Text

这是一个错误吗?如果是,是否有解决方法?
或者我只是做错了什么?

2 个答案:

答案 0 :(得分:1)

这不是一个错误:ItemStringFormat只是“数据模板的一个快捷方式,其中文本块绑定到绑定中设置的指定字符串格式的值”。但Text通常在IsEditable为真时表示用户输入。如果列表中包含除字符串以外的任何内容,则最好使用SelectedItem而不是Text。在任何情况下,以下代码都会将格式重新应用于文本:

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

答案 1 :(得分:0)

我知道这可能为时已晚,无法帮助OP,但万一其他人偶然发现了这个......

我将用于解决其他答案评论中提到的OP的真正问题的解决方案是使用IValueConverter

以下是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();
    }
}

以下是你如何使用它(取自修改后的问题):

<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>

由于{{1},这会导致项目在ComboBox中显示为“## Foo ##”,“## Bar ##”和“## Baz ##”被设置为“## {0} ##”。此外,由于ItemStringFormat VMProp被设置为“## {0} ##,因此ViewModel上的FormatConverter属性会在选择时以相同的格式分配值”

请注意,即使我使用ConverterParameter属性与原始问题保持一致,我也建议ComboBox.Text属性更合适。 ;)