有没有办法转换用作ItemsSource的集合的成员?

时间:2011-09-21 19:30:11

标签: wpf

在WPF中,您可以使用IValueConverter或IMultiValueConverter将数据绑定值从int转换为Color.

我有一组Model对象,我想将它们转换为ViewModel表示,但在这种情况下,

<ListBox ItemsSource="{Binding ModelItems, 
     Converter={StaticResource ModelToViewModelConverter}" />

将编写转换器以立即转换整个集合ModelItems

我希望单独转换集合的项目,有没有办法做到这一点?

3 个答案:

答案 0 :(得分:25)

您无法在集合本身上设置转换器,因为它会将集合作为输入。你有两个选择:

  1. 确保您的转换器也可以处理集合(IEnumerable)。
  2. 在项目模板中使用转换器。
  3. 如果您想使用第二种方法,请使用以下内容:

    <ListBox ItemsSource="{Binding ModelItems}">
      <ListBox.ItemTemplate>
        <DataTemplate>
          <ContentPresenter Content="{Binding Converter={StaticResource ModelToViewModelConverter}}" 
                            ContentTemplate="{StaticResource MyOptionalDataTemplate}"/>
        </DataTemplate>
      </ListBox.ItemTemplate>
    </ListBox>
    

    如果您不需要自定义数据模板,则可以跳过ContentTemplate属性。

答案 1 :(得分:2)

是的,你可以。它的作用与IValueConverter相同。您只需将Convert方法的value参数视为集合。

以下是转换集合的示例:

public class DataConvert : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        ObservableCollection<int> convertible = null;
        var result = value as ObservableCollection<string>;

        if (result != null)
        {
            convertible = new ObservableCollection<int>();
            foreach (var item in result)
            {
                if (item == "first")
                {
                    convertible.Add(1);
                }
                else if (item == "second")
                {
                    convertible.Add(2);
                }
                else if (item == "third")
                {
                    convertible.Add(3);
                }
            }
        }

        return convertible;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

在这种情况下只是一个概念证明,但我认为它应该很好地展示这个想法。 转换器从简单的字符串集转换为:

ModelItems = new ObservableCollection<string>();
        ModelItems.Add("third");
        ModelItems.Add("first");
        ModelItems.Add("second");

成一个对应于字符串含义的整数集合。

这里是相应的XAML(loc是当前程序集的引用,其中是转换器):

<Window.Resources>
    <loc:DataConvert x:Key="DataConverter"/>
</Window.Resources>
<Grid x:Name="MainGrid">
    <ListBox ItemsSource="{Binding ModelItems, Converter={StaticResource DataConverter}}"/>
</Grid>

如果你想进行双向绑定,你还必须实现转换回来。根据使用MVVM的经验,我建议使用类似工厂模式的东西从ViewModel中的Model转换到后退。

答案 2 :(得分:0)

这是另一个例子。我正在使用MVVM Caliburn Micro。在我的例子中,MyObjects是一个枚举列表。

<ListBox x:Name="MyObjects">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <TextBlock Text="{Binding ., Converter={StaticResource MyConverter}}"/>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>