我们正在使用Telerik的RadGridView来显示数据,并绑定到业务对象列表。大多数数据都是这样加载的
[DetailList] // like 20+ lists like this
public List<BusinessObject> BusinessObjects { get; } = new List<BusinessObject>();
private void FillDetail(ObjectContainingLotsOfInfo object)
{
try
{
this.BusinessObjects.AddRange(object.BusinessObjects.Linq);
// Where Linq is some sort of filter or SelectMany statement.
this.RefreshLists();
}
catch (Exception exception)
{
Trace.WriteLine(exception);
this.ErrorMessage = exception.Message;exception.Message));
}
}
private void RefreshLists()
{
var properties = this.GetType().GetProperties().Where(prop => prop.IsDefined(typeof(DetailList), false));
foreach (PropertyInfo item in properties)
{
Trace.WriteLine($"Refreshing the DetailList.{item.Name} property for {this.Identifier}");
this.RaisePropertyChanged(item.Name);
}
}
应用程序从一开始就使用async,一旦从任务中的检索器加载数据,就会调用fill方法。但是,在数据从API返回之前,用户可以导航到网格所在的位置(使用UI线程)。如果在调用填充数据方法之前网格视图初始化,则网格将永远保持为空。如果调用填充数据,则网格加载就可以了。现在,我将所有列表都写入了ObservableCollections,并引用了Microsoft.Practices.Prism来使用它对AddRange的定义,即使我在加载数据之前进入网格,一切都运行正常。但是一旦加载了数据,我们就不会以任何方式改变它,不添加或删除行,并且使用如此多的ObservableCollections会有性能损失。有一个更好的方法吗?有没有办法让RaisePropertyChanged在加载数据时做它的工作?
修改 DetailList的定义如下:
public class DetailListAttribute: Attribute
{
}
答案 0 :(得分:1)
我们假设您有一个名为List<POCO>
的{{1}}媒体资源。在其中实现传统的INPC内容。像往常一样将它绑定到某个地方Foo
。当异步方法完成数据获取后,将 new ItemsSource
分配给List<POCO>
:
Foo
Foo = pocoFromWherever.ToList();
setter引发Foo
。你很好。您可以从另一个线程执行此操作,而无需调用UI线程。
我建议使用ReadOnlyCollection<POCO>
而不是PropertyChanged
来预防任何可能存在的误解,即集合只能被替换而不能被修改。
List<POCO>
我多年来一直在WPF中使用这种模式。不需要聪明。
您可能还希望将setter设为私有,具体取决于要求。