Question

Je construis une application wpf en utilisant MVVM. J'ai viewModels le chargement paresseux d'emploi comme ci-dessous:

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

La vue a les AssignmentViewModels dans un ListView et les Notes dans un ListBox avec un modèle de données.

Lorsque j'affiche un des modèles AssignmentViewModels comportant 160 éléments, il faut 1 000 ms pour le charger. Je pensais que c'était à cause de la propriété Notes qui récupérait une table de base de données avec 1,5 million de lignes. Je l'ai vérifiée et il n'a fallu que 60 ms pour remplir la liste Notes. Donc, je suppose que c'est la liaison de données du chargement des 160 éléments dans la liste. Mais cela ne devrait pas être le cas, car les listBox virtualisent leur contenu (je l’ai surveillé et vérifié que les éléments se trouvaient dans un stackpanel de virtualisation).

Donc, je suis perdue, je ne sais pas comment savoir ce qui prend les 940 ms supplémentaires.

Que puis-je faire pour retrouver cette trace? Les performances sont essentielles et je ne sais pas comment les améliorer.

Était-ce utile?

La solution

Sans savoir à quoi ressemble l'interface utilisateur, il est possible qu'un élément de l'interface utilisateur la ralentisse, comme si vous utilisiez beaucoup BitmapEffects.

Vous pouvez également passer de votre liste à une ObservableCollection, comme la liaison à cela peut être considérablement plus rapide qu’une liste .

Il existe également de bons outils de profilage des performances qui peuvent vous aider. vous.

Autres conseils

Pouvons-nous voir votre code XAML?

Si votre listbox se trouve dans un stackpanel (ou un contrôle similaire), la listbox ne virtualisera pas ses entrées.

Ceci virtualisera:

<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>

Cela ne va pas:

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

Dans la pile, la liste déroulante sera rendue à sa hauteur maximale et dépendra de la pile pour le défilement. (Pas de virtualisation)

À l'intérieur de la grille, la liste déroulante sera rendue à la hauteur de la ligne de la grille et utilisera son propre visualiseur de défilement. (Virtualisation)

Vous pouvez également définir les propriétés Height ou MaxHeight dans la zone de liste au lieu de les insérer dans une grille, mais si vous utilisez un stackpanel, je pense que vous souhaitez un redimensionnement automatique.

Notez que vous ne pouvez pas tricher en plaçant le stackpanel à l'intérieur de la grille; votre listbox doit pouvoir dériver une hauteur maximale quelque part.

Avez-vous essayé les tests de performances sans chargement paresseux?

De plus, dans quelle mesure vos DataTemplates / Views pour vos éléments sont-ils compliqués? Essayez d’exécuter un test avec des représentations TextBlock simples pour vous assurer que vos vues ne sont pas compliquées.

Je voudrais examiner de nouveau le code SQL et s’assurer que votre collection est pleine. En réalité, L2S ne sera pas peuplé tant que vous n'énumérerez pas le résultat.

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: appelez .ToList () immédiatement après le retour des données. Vous verrez beaucoup plus d’activités dans la couche de données qui n’auraient peut-être pas eu lieu avant votre couche d’entreprise ou votre couche d’interface utilisateur.

Je l'ai compris. J'avais un bloc de texte qui nécessitait un habillage textuel, car il est parfois très volumineux. J'ai explicitement défini la largeur de celui-ci (afin qu'il soit renvoyé à l'intérieur) dans le modèle de données et pour une raison quelconque, le VirtualizingStackPanel situé dans le ListBox réalise tous les éléments de la liste. Je l'ai retravaillé pour l'adapter à une grille telle que ..

<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>

Cela a entraîné le chargement rapide de la zone de liste. Merci à vous pour vos réponses, ils m'ont amené sur le bon chemin.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top