Reputation: 491
We are using Telerik's RadGridView to display data, binding to lists of business objects. Most of the data is loaded as such
[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);
}
}
The application uses async from the start, and the fill method is called once the data is loaded from a retriever in a task. However, the user can navigate to where the grids are located (using the UI thread) before the data comes back from the API. If the grids views initialize before the fill data method is called the grids stay empty, forever. If fill data is called then the grids load it is fine. Now, I made all the Lists into ObservableCollections, and referenced Microsoft.Practices.Prism to use it's definition for AddRange, and everything worked fine even when I went to the grids before the data loaded. But once the data is loaded in we won't be changing it in any way, no adding or removing rows, and there is a performance hit for using so many ObservableCollections. Is there a better way to do this? Is there a way to make RaisePropertyChanged do it's job when the data is loaded?
edit The definition of DetailList is given below
public class DetailListAttribute: Attribute
{
}
Upvotes: 2
Views: 141
Reputation: 37059
Let's say you have a List<POCO>
property named Foo
. Implement the conventional INPC stuff in it. Bind it as usual to some ItemsSource
somewhere. When the async method finishes getting the data, assign a new List<POCO>
to Foo
:
Foo = pocoFromWherever.ToList();
The Foo
setter raises PropertyChanged
. You're fine. You can do this from another thread without having to invoke into the UI thread, too.
I'd recommend using ReadOnlyCollection<POCO>
instead of List<POCO>
, to forestall any potential misunderstandings about the fact that the collection can only be replaced, not modified.
Foo = new ReadOnlyCollection<POCO>(pocoFromWherever.ToList());
I've been using that pattern for this type of thing in WPF for years. No need to get clever.
You might also want to make the setter private, depending on requirements.
Upvotes: 1