使用转换器绑定组合框文本属性



在以下场景中使用WPF组合框时遇到问题:

ViewModel

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

  • 提供代表所选项目的T类型的属性。

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

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

查看

我的组合框绑定到集合和所选项目属性:

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

问题

使用convert可以正确显示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,当然不能转换。

摘要

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

编辑

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

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 
      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上,转换列表框中的显示值

我甚至将这个片段与来自xaml中定义的ObjectDataProvider的Enum集合一起使用。我的枚举具有DisplayString属性,组合框可以很好地显示枚举的字符串值表示。

HTH

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

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

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

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

最新更新