是否可以将“外部”泛型集合类型传递到类中,而无需指定集合包含的项的内部类型?

时间:2013-11-27 14:32:02

标签: c# windows-runtime

我正在编写一个MVVM架构的应用程序。我有一个View库和一个ViewModels库。

ViewModel需要持久保存一系列内容。我希望从集合的具体类型中抽象出ViewModel,但只知道它派生自ObservableCollection并实现一个名为IIncrementalObservableCollection的接口。

public class ViewModel<TObservableCollection> : ViewModelBase
where TObservableCollection : ObservableCollection<ThingType>, IIncrementalObservableCollection<ThingType>, new()

我在View层中有一个类,它提供了一个自定义的ObservableCollection实现,如下所示:

public class IncrementalObservableCollection<T> : ObservableCollection<T>, ISupportIncrementalLoading, IIncrementalObservableCollection

在View层中,我可以像这样实例化这个ViewModel:

new ViewModel<IncrementalObservableCollection<ThingType>>(null, null);

然而,问题是ThingType是一个模型对象。 View不应该告诉ViewModel集合中应该包含什么类型的对象。

简而言之;我希望能够将集合类型传递给ViewModel,但是然后让View Model负责该类型的实例化,并且至关重要的是将在集合中保存哪些类型。

所以我希望能够像这样实例化ViewModel:    new ViewModel<IncrementalObservableCollection>(null, null); - 没有ThingType泛型参数。

编辑以澄清 My View图层是Windows 8应用程序,我的ViewModel图层是PCL。我在Views层中的xaml中声明了一个GridView,它绑定到ViewModel上的ObservableCollection。问题是,对于GridView支持增量加载数据,ObservableCollection必须实现ISupportIncrementalLoading。我无法在ViewModel层中执行此操作,因为作为PCL,它无权访问ISupportIncrementalLoading。所以我认为我需要在View层中创建一个继承自ObservableCollection和ISupportIncrementalLoading的具体类型...然后还实现在ViewModel层中定义的ISupportIncrementalLoading(称为IIncrementalObservableCollection)的自定义版本。

所以从根本上说,我希望ViewModel能够利用View层提供的具体集合类。所以我的问题归结为:GridView在ViewModel属性上需要ISupportIncrementalLoading,但ViewModel层无法访问ISupportIncrementalLoading。

感谢

1 个答案:

答案 0 :(得分:1)

那更好。

这就是我解决它的方法。没有太多解释,因为最好的解释是代码;)。

public class IncrementalLoadingCollection<T> : ObservableCollection<T>, ISupportIncrementalLoading 
{
    // todo; write a lot of magic here.(VIEW)


}


// IN PCL
public abstract class PortableFactory
{
    private static PortableFactory _factory;

    public static PortableFactory Current
    {
        get
        {
            if (_factory == null)
            {
                throw new InvalidOperationException();
            }
            return _factory;
        }
        set
        {
            _factory = value;
        }
    }

    protected PortableFactory() {
       // note we auto-set current here,
       // which saves an extra step for the caller
        Current = this;            
    }


    public abstract IList<T> GetIncrementalCollection<T>();
}

// IN XAML APP
public partial class App : Application
{
    private PortableFactory _pf = new WPFPortableViewFactory();

    private class WPFPortableViewFactory : PortableFactory
    {
        public override IList<T> GetIncrementalCollection<T>()
        {
            return new IncrementalLoadingCollection<T>();
        }
    }
}


// IN VIEWMODEL
public class ViewModel
{
    public IList<Car> Cars { get; set; }

    public ViewModel()
    {
        Cars = PortableFactory.Current.GetIncrementalCollection<Car>();
    }
}

此处采用的代码(经过少量修改):http://blogs.msdn.com/b/sburke/archive/2011/02/03/using-observablecollection-with-the-portable-library-tools-ctp.aspx