【问题标题】:Is it possible to pass in an "outer" generic collection type into a class without specifying the inner type of the items that the collection contains?是否可以在不指定集合包含的项目的内部类型的情况下将“外部”通用集合类型传递给类?
【发布时间】:2013-11-27 14:32:02
【问题描述】:

我正在编写一个具有 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&lt;IncrementalObservableCollection&gt;(null, null); - 没有 ThingType 泛型参数。

编辑澄清 我的 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。

谢谢

【问题讨论】:

  • 现实生活中的问题是什么?解释你为什么要尝试做你所做的事情。持久性通常发生在由视图模型控制的数据访问层中。至于你的问题;不。你问什么没有意义;无论哪种方式,你都必须牺牲一些东西。
  • 我已添加说明。这是一个很难描述的问题,所以我很乐意进一步解释。

标签: c# windows-runtime


【解决方案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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 2021-12-04
  • 2014-09-11
  • 2012-07-07
相关资源
最近更新 更多