【问题标题】:Binding ComboBox Text property using a converter使用转换器绑定 ComboBox Text 属性
【发布时间】:2012-04-06 18:59:59
【问题描述】:

我在以下场景中使用 WPF ComboBox 时遇到问题:

视图模型

  • 提供ObservableCollection<T>;此集合包含用户可以选择的项目列表。

  • 提供一个T 类型的属性,表示所选项目。

用户应能够从ObservableCollection<T> 中的项目中选择现有项目或通过键入字符串表示添加新项目。

我有一个转换器可以将T 类型的项目转换为string,反之亦然。

查看

我的 ComboBox 绑定到集合和选定项属性:

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

用于正确显示项目的数据模板:

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

问题

ComboBox 下拉列表中的项目使用转换正确显示。 ComboBoxTextBox中显示的选中项显示不正确;不使用我的转换器,而是使用ToString 方法。

是否可以为 Text 属性指定转换器?我尝试使用以下代码:

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

这解决了显示问题,但现在我在转换器ConvertBack 方法中得到了 T 的Type.FullName - 当然不能转换。

总结

我希望用户能够从集合中选择一个项目,允许他通过输入字符串表示来添加新项目。集合中的项目应使用转换器在字符串和对象表示之间进行转换。转换应在下拉列表和 ComboBox 的文本框中进行。

编辑

这是我的转换器中的代码 - 没有魔法,只是简单的转换:

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

}

好的,现在我找到了我想要的东西:

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

这正是我想要的;我可以选择预定义的值,用户可以自己添加值。是否可以使用 ComboBox 做到这一点?

【问题讨论】:

  • 为什么不能转换回来? Type.GetType((string)value, true, true) 并在需要时使用 Activator。
  • 也可以给我们转换器代码吗?
  • @Silvermind 我添加了转换器代码。问题是type.GetType((string)value, true, true) 仍然要求该值是实际值,但它实际上是一个包含Type.FullNamestring

标签: wpf text binding combobox converter


【解决方案1】:

如果有人面临同样的问题并且不想处理要绑定的字符串属性。

你可以使用下面的

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

请注意,绑定是在 SelectedValue 上完成的,而不是 SelectedItem。 然后将显示转换器添加到 Text & Itemtemplate 属性中。

  • 在 Text 属性上,它将用于转换所选项目的显示值。
  • 在 ItemTemplate 上,转换列表框中的显示值

我什至将此 sn-p 与来自 xaml 中定义的 ObjectDataProvider 的 Enum 集合一起使用。我的枚举具有 DisplayString 属性,并且组合框可以很好地显示枚举的字符串值表示。

HTH

【讨论】:

    【解决方案2】:

    我现在使用不同的方法来解决这个问题:

    我的视图模型提供了一个可观察的集合和一个字符串属性。集合绑定到 ComboBox 的 ItemsSource 属性,选中项绑定到字符串属性。

            <ComboBox
                ItemsSource="{Binding Path=MyCollection}" 
                Text="{Binding Path=MyProperty, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"
                IsReadOnly="False" IsEditable="True"/>
    

    UpdateSourceTrigger=LostFocus 部分用于防止不必要的更新。

    【讨论】:

      猜你喜欢
      • 2012-12-05
      • 1970-01-01
      • 2012-03-10
      • 2012-03-27
      • 1970-01-01
      • 1970-01-01
      • 2015-03-14
      • 2013-10-09
      • 1970-01-01
      相关资源
      最近更新 更多