Frage

Ich baue eine WPF-Anwendung mit MVVM. Ich habe die Viewmodel beschäftigen verzögertes Laden wie folgt:

public class AssignmentsViewModel
{

    List<AssignmentViewModel> _Assignments;
    public List<AssignmentViewModel> Assignments
    {
        get
        {
            if (_Assignments == null)
                _Assignments = new List<AssignmentViewModel>(Data.GetAssignments());
            return _Assignments;
        }
        set { _Assignments = value; }
    }
}
public class AssignmentViewModel
{
    List<NoteViewModel> _Notes;
    public List<NoteViewModel> Notes
    {
        get
        {
            if (_Notes == null)
                _Notes = new List<NoteViewModel>(Data.GetNotes());
            return _Notes;
        }
        set { _Notes = value; }
    }
}

Die Ansicht hat die AssignmentViewModels in einem Listview und die Schuldverschreibungen in einer List-Box mit einem Datatemplate.

Wenn ich eine der AssignmentViewModels anzuzeigen, die 160 Elemente hat es 1000 ms dauert zu laden. Ich dachte, es wegen der Eigenschaft Hinweise war mit 1,5 Millionen Zeilen aus einer Datenbanktabelle greifen. Ich habe es und es nur 60ms nahm die Notes-Liste zu füllen. Also ich nehme an, dass es die Datenbindung des Ladens der 160 Elemente in der Listbox ist. Aber das sollte nicht der Fall sein, weil Listboxen ihren Inhalt virtualisieren (I snooped es und bestätigt, dass die Elemente in einem Virtualisieren von Stackpanel sind).

Also ich ratlos bin, weiß ich nicht, wie Sie herausfinden, was den zusätzlichen 940 ms nimmt.

Was kann ich tun dies, um die Spur zu kommen? Leistung ist der Schlüssel, und ich weiß nicht, wie es zu verbessern.

War es hilfreich?

Lösung

Ohne zu wissen, was die UI ist wie die Möglichkeit besteht, dass etwas aus dem UI es wie eine große Nutzung von BitmapEffects verlangsamt.

Auch können Sie Ihre Liste wechseln auf eine ObservableCollection, wie zu, dass die Bindung wesentlich schneller als eine Liste sein kann.

Es gibt auch einige gute Leistungsprofil Tools rel="nofollow, die helfen können Sie.

Andere Tipps

Können wir sehen XAML?

Wenn Sie Ihr listbox in einem Stackpanel (oder eine ähnliche Steuerung) die Listbox wird seine Einträge nicht virtualisieren.

Dies wird virtualisieren:

<Grid>
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="*" />
  </Grid.RowDefinitions>

  <Label Grid.Row=0>Your label here</Label>
  <ListBox Grid.Row=1 Your properties here... />

</Grid>

Dies wird nicht:

<StackPanel>
  <Label>Your label here</Label>
  <ListBox Your properties here... />
</StackPanel>

Im Inneren des Stackpanel der Listbox auf seine maximale Höhe machen wird und hängen von der Stackpanel zum Scrollen. (No Virtualisieren)

Im Innern des Gitters wird das Listenfeld in das Netz Zeilenhöhe machen und seine eigene Scroll verwenden. (Virtualisieren)

Sie können auch nur die Höhe oder MaxHeight Eigenschaften auf dem Listenfeld gesetzt, anstatt sie in einem Raster setzen, aber wenn Sie ein Stackpanel mit Mir vermute, dass Sie die automatische Anpassen von einer Art wollen.

Beachten Sie, dass Sie nicht, indem Sie den Stackpanel innerhalb des Gitters zu betrügen; Ihr listbox hat eine maximale Höhe abzuleiten von irgendwo zu können.

Haben Sie perf-Tests versuchen w / o verzögertes Laden?

Auch, wie kompliziert Ihre Datatemplates / Ansichten für Ihre Artikel? Versuchen Sie, einen Test w / einfache TextBlock- Darstellungen ausgeführt, um sicherzustellen, es ist nicht, wie kompliziert Ihre Ansichten sind.

Ich würde noch einen Blick auf die SQL nehmen und stellen Sie sicher, dass Ihre Sammlung füllt. L2S wird nicht wirklich bevölkern, bis Sie das Ergebnis aufzuzählen.

private IEnumerable<Thing> Method1()
{
    return _db.Things.Where(t => t.ID > 500);
}
private void Method2()
{
    var things = Method1(); // here, 'things' doesn't really contain anything
                            // even though you've already done the db fetch
    foreach (var thing in things) // 'things' gets populated here.
    {
        // do something
    }
}

ex: Rufen Sie .ToList() unmittelbar nachdem die Daten zurückgegeben werden. Sie werden viel mehr Aktivität in der Datenebene sehen, die bis Ihr Unternehmen oder UI-Ebene geschieht möglicherweise nicht haben.

ich es herausgefunden. Ich hatte einen Textblock, den TextWrapping benötigt, weil es manchmal recht groß ist. Ich habe ausdrücklich die Breite davon (so dass sie wickeln würde) in der Datatemplate und aus irgendeinem Grund, der die VirtualizingStackPanel in der List-Box bewirkt, dass alle Elemente in der Liste zu realisieren. Ich überarbeitete sie es in ein Raster zu passen wie so ..

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="3*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid Grid.Column="0">
       ....
    </Grid>
    <ListBox Grid.Column="1" ItemsSource="{Binding}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" >
       ...//DataTemplate
    </ListBox>
</Grid>

Dies verursachte die listbox schnell zu laden. Vielen Dank für Ihre Antworten, die sie brachte mich auf dem richtigen Weg.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top