有没有办法创建一个转换它的源的集合视图?

时间:2013-07-09 10:36:45

标签: c# wpf observablecollection icollectionview

我有一个ObservableCollection<T>,它拥有一种类型的对象。我需要它作为几个列表控件的源,但我也想转换数据。为简单起见,假设我有一个ObservableCollection<int>并且希望得到一个返回字符串的ICollectionView - 也许只是转换为字符串的整数。

有没有办法创建这样的视图?

好像:

var view = new MagicalCollectionView(myCollection, x => x.ToString())?

3 个答案:

答案 0 :(得分:1)

集合视图是关于排序,过滤,分组。它们与数据转换无关。

实际上,在任务解释中没有直接需要这种收集。您只需要正确设置 view ,例如为源集合中的项目提供正确的DataTemplate

public class MyEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class MyViewModel
{
    public ObservableCollection<MyEntity> Entities { get; private set; }
    public ICollectionView EntitiesView
    {
        if (view == null)    
        {
            view = new ListCollectionView(Entities);
        }
        return view;
    }
    private ICollectionView view;
}

XAML:

<DataTemplate DataType="{x:Type local:MyEntity}">
    <!-- This "transforms" visual representation of your entity, but the entity itself (and its container) remains unchanged -->
    <TextBlock Text="{Binding Name}"/>
</DataTemplate>

<强>更新即可。 根据你的评论,我将实体包装到视图模型中。而且,这是视图模型的目的:

public class MyEntityViewModel
{
    private readonly MyEntity model;

    public MyEntityViewModel(MyEntity model)
    {
        this.model = model;
    }

    public int MyInt
    {
        get { return model. // some logic to retrieve int ... }
    }

    public string MyString
    {
        get { return model. // some logic to retrieve string ... }
    }
}

然后,我将控件绑定到视图模型集合而不是模型的集合:

public class MyViewModel
{
    public MyViewModel(ICollection<MyEntity> entities)
    {
        this.Entities = new ObservableCollection<MyEntityViewModel>(entities.Select(e => new MyEntityViewModel(e)));

        // this will keep two collections synchronized:
        this.Entities.CollectionChanged += (sender, args) =>
        {
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    entities.Add((MyEntity)e.NewItems[0]);
                    break;
                case NotifyCollectionChangedAction.Remove:
                    entities.Remove((MyEntity)e.OldItems[0]);
                    break;
                case NotifyCollectionChangedAction.Replace:
                    entities.Remove((MyEntity)e.OldItems[0]);
                    entities.Add((MyEntity)e.NewItems[0]);
                    break;
                case NotifyCollectionChangedAction.Reset:
                    entities.Clear();
                    break;
            }
        }
    }            

    public ObservableCollection<MyEntityViewModel> Entities { get; private set; }
}

这将使您的数据类与额外属性保持清晰,这些属性仅供查看。

答案 1 :(得分:0)

您可以使用LINQ进行投影

myCollection.Select(x=> int.Parse(x))

将解析集合中的每个元素并返回一个整数

答案 2 :(得分:0)

我主要同意丹尼斯的观点,但是,使用绑定转换器对底层边界值进行最终转换可能会对此有所帮助。

我假设您有一个类型集合,并希望在不同的地方对数据进行不同的实时投影。

您可以在每种情况下绑定到同一个集合,并为每个案例“插入”不同的自定义转换器,可能在自定义DataTemplate中。

http://www.silverlightshow.net/items/Data-Conversion-in-Silverlight-2-Data-Binding.aspx

Silverlight演示,但它是一样的。

相关问题