【问题标题】:Is there any way to convert the members of a collection used as an ItemsSource?有没有办法转换用作 ItemsSource 的集合的成员?
【发布时间】:2011-09-21 19:30:11
【问题描述】:

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

我有一个模型对象的集合,我想将它们转换为它们的 ViewModel 表示,但在这种情况下,

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

将编写转换器以一次转换整个集合ModelItems

我希望单独转换集合中的项目,有没有办法做到这一点?我可能想使用CollectionViewSource 并有一些过滤逻辑,所以我不想每次发生变化时都遍历整个集合。

【问题讨论】:

    标签: wpf


    【解决方案1】:

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

    1. 确保您的转换器也可以处理集合 (IEnumerable)。
    2. 在项目模板中使用转换器。

    如果您想使用第二种方法,请使用以下内容:

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

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

    【讨论】:

      【解决方案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 中的模型和向后转换。

      【讨论】:

      • 谢谢 louie,但这并不是我真正想要的,我可能想使用 CollectionViewSource 并有一些过滤逻辑,所以我不想每次都遍历整个集合时间发生了变化,因此我的问题的最后一句话。
      • 对不起,我没有看到最后一句话。祝你好运。
      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-15
        • 2021-05-17
        相关资源
        最近更新 更多