【问题标题】:WPF: Binding large collections to GridControlWPF:将大型集合绑定到 GridControl
【发布时间】:2015-01-12 10:18:59
【问题描述】:

我刚刚开始我的第一个 WPF 项目,今天早上我遇到了一个问题。 有这么多位置 (50.000) 我想绑定到 GridControl

    public void BindData()
    {
        //disabling the control seemed to shorten the UI lock.
        gcLocations.IsEnabled = false; 

        Task.Factory.StartNew(() =>
        {
            gcLocations.SetPropertyThreadSafe("ItemsSource", OceanData.OceanPorts.Values);
        });

        gcLocations.IsEnabled = true; 
    }

    public static void SetPropertyThreadSafe(this Control control, string propertyName, object value)
    {
        Type type = control.GetType();
        var prop = type.GetProperty(propertyName);

        if(prop == null)
        {
            throw new Exception(string.Format("No property has been found in '{0}' with the name '{1}'", control, propertyName));
        }

        object[] param = new object[] { propertyName, prop.PropertyType, value };
        if(prop.PropertyType != typeof(object) && prop.PropertyType != value.GetType())
        {
            throw new Exception(string.Format("Property types doesn't match - property '{0}' (type:{1}) and value '{2}'(type:)", param));         
        }

        if(control.Dispatcher.CheckAccess())
        {
            prop.SetValue(control, value);
        }
        else
        {
            control.Dispatcher.BeginInvoke(new Action(() =>
            {
                prop.SetValue(control, value);
            }), DispatcherPriority.ContextIdle, null);
        }
    }

因为我希望我的应用程序保持对用户的响应,所以我一直在寻找一种替代方法来一次性绑定这些数据。所以我想到了这个想法..是否可以在界面发生锁定时暂停绑定操作,以便界面可以自行更新?我对编程很陌生,所以请原谅我的无知:)

谢谢~~

【问题讨论】:

  • 据我所知,您的代码正在向 GridControl 添加 50'000 多个控件……这需要一些时间,而且会在 UI 线程上发生!是否需要同时显示所有 50'000 个控件?还是滚动查看它们?这个问题急需对您的数据进行某种虚拟化......
  • 尝试使用ListView 进行这种显示,并使用GridView 为您的控件定义自定义视图。当您使用ListView 时,您可以使用VirtualisingStackPanel 的好处,它提供了虚拟化,因此得名:-)。如果您需要更多信息,请告诉我。
  • 感谢您的回复! @olitee 一点也不。但在某些情况下,用户需要搜索位置并编辑属性。我使用 Devexpress 网格控件,它具有非常好的过滤数据。不幸的是,列表视图没有这个功能。我必须为此创建一个自定义控件,所以我宁愿继续使用 gridcontrol。
  • DevExpress 的 GridControl 应默认为开箱即用地虚拟化您的数据。您是否已经尝试过简单地将值集合数据绑定到您的 ItemsSource?什么底层集合?它已经在内存中了吗?
  • @olitee,我目前正在将值绑定在内存中的 Directory 中。 “默认为开箱即用虚拟化数据”是什么意思?

标签: c# wpf multithreading data-binding


【解决方案1】:

DevExpress GridControl 支持数据虚拟化,从而仅构建在屏幕上可见的控件/项目并将其添加到可视化树中。此外,这些可见控件通常会在您向下滚动列表时被回收,从而节省重建它们的成本。

如果您不熟悉虚拟化,请考虑一个简单的列表视图示例:您可以将包含 10,000 个项目的数据源绑定到它,但任何时候用户可能只能看到 20 个项目。虚拟化机制确保仅创建可见的列表项。如果没有此功能,列表框将不得不创建 10,000 个 WPF 列表项(其中可能包含多个控件或 UI 元素),并将它们保存在内存中并将它们添加到可视化树中,即使它们不可见。 WPF 控件只能添加到 UI 线程上的可视化树中,这将导致您的代码挂起。

DevExpress GridControl 似乎支持开箱即用的虚拟化,但可以通过使用它们自己的 DevExpress Datasource 类来增强它。 Check out this documentation ...您可能需要使用 LinqServerModeDataSourceLinqInstantFeedbackDataSource 类来为您提供所需的性能。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-25
  • 1970-01-01
  • 1970-01-01
  • 2010-09-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多