2017-06-30 4 views
2

Wir verwenden Teleriks RadGridView, um Daten anzuzeigen, die an Listen von Geschäftsobjekten gebunden sind. Die meisten Daten geladen wird als solcheGibt es eine bessere Möglichkeit, Listen ohne ObservableCollection zu laden?

[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); 
     } 
    } 

Die Anwendung verwendet async von Anfang an, und die Fill-Methode aufgerufen wird, wenn die Daten von einem Retriever in einer Task geladen wird. Der Benutzer kann jedoch zu dem Ort navigieren, an dem sich die Grids befinden (mithilfe des UI-Threads), bevor die Daten von der API zurückgegeben werden. Wenn die Grids-Ansichten initialisiert werden, bevor die Fülldatenmethode aufgerufen wird, bleiben die Grids für immer leer. Wenn Fülldaten aufgerufen werden, laden die Raster es ist in Ordnung. Nun habe ich alle Listen zu ObservableCollections gemacht und Microsoft.Practices.Prism referenziert, um seine Definition für AddRange zu verwenden, und alles funktionierte auch dann, wenn ich vor den geladenen Daten zu den Rastern gegangen bin. Aber sobald die Daten geladen sind, werden wir sie in keiner Weise ändern, keine Zeilen hinzufügen oder entfernen, und es gibt einen Leistungseinbruch für die Verwendung so vieler ObservableCollections. Gibt es einen besseren Weg, dies zu tun? Gibt es eine Möglichkeit, RaisePropertyChanged seine Aufgabe zu machen, wenn die Daten geladen werden?

bearbeiten Die Definition der Detaillist ist unter

public class DetailListAttribute: Attribute 
{ 
} 
+0

Haben Sie sich mit der Verwendung von Reactive Extensions (https://msdn.microsoft.com/en-us/library/hh242985(v=vs.103).aspx) befasst? Sie könnten ein IObservable einrichten, das einmal aktualisiert wird, sobald die Daten verfügbar sind, und dann abgeschlossen wird. – Necoras

+2

Bei einer Eigenschaft 'List Foo {/ * INPC stuff * /}', wenn Sie die Daten erhalten, weisen Sie 'Foo = pocoClasses.ToList();' zu. Füllen Sie keine bestehende "Liste " auf. Weisen Sie der Eigenschaft eine neue zu. Lassen Sie den Setter "PropertyChanged" auslösen. Erledigt. –

+0

@EdPlunkett Also schlagen Sie vor, einen Setter für die Listen zu implementieren? – kleineg

Antwort

1

Angenommen, Sie haben eine List<POCO> Eigenschaft Foo Namen gegeben haben. Implementiere das herkömmliche INPC-Material darin. Binden Sie es wie immer an irgendeinen ItemsSource irgendwo. Wenn die Asynchron-Methode beendet die Daten bekommen, weisen eine neueList<POCO> zu Foo:

Foo = pocoFromWherever.ToList(); 

Die Foo Setter PropertyChanged erhöht. Du bist in Ordnung. Sie können dies von einem anderen Thread aus tun, ohne auch auf den UI-Thread zugreifen zu müssen.

Ich würde ReadOnlyCollection<POCO> anstelle von List<POCO> empfehlen, um mögliche Missverständnisse über die Tatsache zu vermeiden, dass die Sammlung nur ersetzt, nicht geändert werden kann.

Foo = new ReadOnlyCollection<POCO>(pocoFromWherever.ToList()); 

Ich habe dieses Muster für diese Art von Sache in WPF seit Jahren verwendet. Kein Grund, clever zu werden.

Sie können den Setter je nach Bedarf auch privat gestalten.

+0

Ich konnte keine ReadOnlyCollection verwenden, weil wir die Daten entsorgt haben, wenn die Registerkarte, auf der sie sich befindet, geschlossen ist, aber das hat perfekt funktioniert, danke. – kleineg

+0

Wie ist eine ReadOnlyCollection ein Problem dafür? –

+0

Wenn ich es mit einer ReadOnlyCollection implementiert habe, gab es eine Ausnahme, als die Methode clear aufgerufen wurde, die besagt, dass die Sammlung nicht geändert werden konnte. – kleineg

Verwandte Themen