WPF:将大型集合绑定到 GridControl
WPF: Binding large collections to GridControl
我刚刚开始我的第一个 WPF 项目,今天早上我 运行 遇到了一个问题。
我想绑定到 GridControl 的大量位置集合 (50.000)。
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);
}
}
因为我希望我的应用程序保持对用户的响应,所以我一直在寻找一种替代方法来一次绑定此数据。所以我想到了这个想法.. 是否可以在界面发生锁定时暂停绑定操作,以便界面可以自行更新?我对编程很陌生,所以请原谅我的 igno运行ce :)
谢谢~~
DevExpress GridControl 支持数据虚拟化,因此只有 controls/items 在屏幕上可见的内容会被构建并添加到可视化树中。此外,当您向下滚动列表时,这些可见控件通常会被回收,从而节省重建它们的成本。
如果您不熟悉虚拟化,请考虑一个简单的列表视图示例:您可以将包含 10,000 个项目的数据源绑定到它,但在任何时候用户可能只能看到 20 个项目.虚拟化机制确保只创建可见的列表项。如果没有此功能,列表框将不得不创建 10,000 个 WPF 列表项(它们可能包含多个控件或 UI 元素),并将它们保存在内存中并将它们添加到可视化树中,即使它们不是可见的。 WPF 控件只能添加到 UI 线程上的可视化树,这将导致您的代码挂起。
DevExpress GridControl 似乎支持开箱即用的虚拟化,但可以通过使用他们自己的 DevExpress 数据源来增强它 类。 Check out this documentation ... it may be you need to make use of the LinqServerModeDataSource or LinqInstantFeedbackDataSource 类 为您提供所需的性能。
我刚刚开始我的第一个 WPF 项目,今天早上我 运行 遇到了一个问题。 我想绑定到 GridControl 的大量位置集合 (50.000)。
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);
}
}
因为我希望我的应用程序保持对用户的响应,所以我一直在寻找一种替代方法来一次绑定此数据。所以我想到了这个想法.. 是否可以在界面发生锁定时暂停绑定操作,以便界面可以自行更新?我对编程很陌生,所以请原谅我的 igno运行ce :)
谢谢~~
DevExpress GridControl 支持数据虚拟化,因此只有 controls/items 在屏幕上可见的内容会被构建并添加到可视化树中。此外,当您向下滚动列表时,这些可见控件通常会被回收,从而节省重建它们的成本。
如果您不熟悉虚拟化,请考虑一个简单的列表视图示例:您可以将包含 10,000 个项目的数据源绑定到它,但在任何时候用户可能只能看到 20 个项目.虚拟化机制确保只创建可见的列表项。如果没有此功能,列表框将不得不创建 10,000 个 WPF 列表项(它们可能包含多个控件或 UI 元素),并将它们保存在内存中并将它们添加到可视化树中,即使它们不是可见的。 WPF 控件只能添加到 UI 线程上的可视化树,这将导致您的代码挂起。
DevExpress GridControl 似乎支持开箱即用的虚拟化,但可以通过使用他们自己的 DevExpress 数据源来增强它 类。 Check out this documentation ... it may be you need to make use of the LinqServerModeDataSource or LinqInstantFeedbackDataSource 类 为您提供所需的性能。