【问题标题】:Implementing Telerik VirtualQueryableCollectionView with MVVM pattern使用 MVVM 模式实现 Telerik VirtualQueryableCollectionView
【发布时间】:2011-10-11 07:49:47
【问题描述】:

我有一个使用 Telerik RadGridView 控件和 Caliburn.Micro MVVM 框架实现的应用程序。由于一些性能问题,我需要实现 Telerik VirtualQueryableCollectionView 来代替正在使用的直接 control-to-ObservableCollection 绑定。原始代码将 RadGridView 的 ItemsSouce 属性绑定到视图模型的 Price 属性。我必须在代码隐藏中消除该绑定和 this:

public PricingView(PricingViewModel vm)
{
    InitializeComponent();

    var dataView = new VirtualQueryableCollectionView()
                         { LoadSize=20, VirtualItemCount = vm.Prices.Count };
    dataView.ItemsLoading += (sender, e) =>
        {
            var view = sender as VirtualQueryableCollectionView;
            if (dataView != null)
            {
                view.Load(e.StartIndex, vm.Prices.Skip(e.StartIndex).Take(e.ItemCount));
            }
        };
    this.PricesGridView.ItemsSource = dataView;
}

由于这段代码只处理 UI 特定的功能并且它是特定于视图实现的,我很满意这段代码属于代码隐藏而不是 ViewModel,因为它会偏离 MVVM 模式来放置对 ViewModel 中的 VirtualQueryableCollectionView 的引用。我不满意的部分是将 ViewModel 的引用传递给 View 的构造函数。有没有一种无需在构造函数中传递引用即可在代码隐藏中获取引用的好方法?

或者有没有更好的方法来做这一切?

【问题讨论】:

    标签: silverlight mvvm telerik telerik-grid


    【解决方案1】:

    我的应用程序是使用 MVVM Light 实现的,在我的例子中,我在 ViewModel 中使用 VirtualQueryableCollectionView 类而不是 View。

    我这样做是因为我认为这个类与ObservableCollection 非常相似,尽管它不是核心类的一部分。 实际上,VirtualQueryableCollectionView 不仅限于 Telerik 控件,还包括许多其他标准控件,例如 ListView

    在我的例子中,获取是在模型中实现的。

    void MainViewModel()
    {
        this.Traces = new VirtualQueryableCollectionView<MyEntityClass>()
        {
            // ViewModel also manages the LoadSize
            LoadSize = this.PageSize,
            VirtualItemCount = myModel.TotalCount
        };
        this.Traces.ItemsLoading += (s, args) =>
        {
            this.Traces.Load(args.StartIndex, 
                             myModel.FetchRange(args.StartIndex, args.ItemCount));
        };
    }
    

    【讨论】:

      【解决方案2】:

      不确定“性能问题”是什么意思,但我假设这意味着当您从 UI 线程填充集合时,它会阻塞应用程序足够长的时间,它似乎没有响应。

      对此有两种常见的解决方案。首先是简单地从后台线程填充您的集合。

      简单的实现是简单地将加载推送到 ThreadPool 线程,然后使用 Dispatcher 编组调用,将 ObservableCollection 的项目添加到 UI 线程。

      一种更好的方法(根本不涉及 ViewModel)是使用 asynchronous bindings. 您将回退配置为向用户指示您正在加载的某个值。有时(视情况而定)您可以使用PriorityBinding 逐渐填充您的用户界面。

      其他替代方法是在显示splash screen 时预先加载和缓存您的数据。它们在 WPF 中有点不同,它不像旧的“在我工作时显示这个表单,然后显示主表单”模式的 winforms。而且,当然,总是有经典的数据分页。它很难编码,但很有效。实际上,我应该说它在 UI 中很难。现在在代码中很容易 (database.Skip(pageNumber * pageSize).Take(pageSize))。

      【讨论】:

      • 感谢您的回复,通过“性能问题”,我指的是进行数据绑定所花费的时间。
      • 我包含的代码片段通过“根据需要”将集合中的数据绑定到控件来解决我遇到的性能问题。事实上,代码在数据收集上使用 Skip() 和 Take() 扩展方法,就像您在答案的最后一行中所做的那样。我看到我没有提到我的环境是 Silverlight。
      猜你喜欢
      • 2013-08-16
      • 1970-01-01
      • 1970-01-01
      • 2011-04-01
      • 1970-01-01
      • 2015-05-08
      • 2011-09-25
      • 1970-01-01
      相关资源
      最近更新 更多