9
votes

BeginUpdate équivalent dans WPF?

Mon problème est que j'ai besoin d'ajouter beaucoup d'éléments à une liste de liste dans WPF. Dans Winforms, vous utiliseriez simplement la méthode BEGTUPDATE (); , ajoutez tout, puis utilisez enfin la méthode endupdate ();

Alors, comment puis-je arrêter le dessin dans une liste WPF jusqu'à ce que chaque article soit ajouté, puis tout attirer en une fois?


0 commentaires

3 Réponses :


5
votes

On dirait que vous pouvez ajouter de manière programmative les éléments à votre case de liste. Une meilleure approche serait de stocker les éléments que vous souhaitez afficher dans un modèle et de lier le modèle au contexte des données de la zone de liste. Cela permettra au WPF de prendre soin des mises à jour de rendu.

Si vous ajoutez des extraits de votre XAML et de votre code à la question (pour nous montrer ce que vous faites actuellement), nous pourrions peut-être fournir une meilleure réponse. p>

EDIT: strong> Ajout d'un exemple très simple. P>

Voici un exemple qui lie un modèle de vue à la fenêtre principale (la vue), puis le XAML déclare que le Les données de la liste de liste sont liées à la propriété Numéros de la vue EM>. P>

MainviewModel.cs strong> P>

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new MainViewModel();
    }
}


6 commentaires

Oui, j'ajoute de manière programmée sur la liste de liste. Eh bien, il n'y a pas beaucoup de code à montrer, car je n'ai pas encore codé toute l'application, je suis simplement testant sur la manière de le faire en utilisant une liste de liste et le code suivant: pour (int i = 0; i <1000; i ++ ) {lbquery.items.add (i); } De toute façon, pourriez-vous me donner un exemple de code de votre solution?


+1, les construire dans une liste d'abord serait beaucoup mieux. Sauf si c'est impossible, alors vous devrez vivre avec les frais généraux d'un redessinement pour chaque ajout.


Si vous pouvez remplir la liste complète rapidement à une fois, vous devriez le faire avant de se lier ... sinon, vous n'avez pas nécessairement de redessinement pour chaque ajout si vous pouvez ajouter un lot à la fois ou similaire.


@Lith listbox.itemsSource = lbquery.items.take (1000); serait l'équivalent dans le code si vous avez la linq disponible. Je voudrais vraiment mettre en place un modèle approprié comme @damian suggère et le faire correctement si j'étais vous.


@Bryan Eh bien, j'essaie de mettre en œuvre la solution de Damian, mais je ne peux pas sembler le faire correctement? Ou plutôt dit; Je ne sais même pas comment?


@Bryan. Merci pour l'exemple. Bien que je n'ai pas vraiment vu une énorme différence en utilisant votre méthode contre la boucle pour la boucle, j'ai toujours appris certaines choses. Quant aux livres, je vais certainement les regarder. Merci encore! Et merci aux autres aussi pour essayer de m'aider =).



15
votes

Utilisez correctement le répartiteur.

Vous devez ajouter des choses à votre liste de liste (ou de sa source de données) à partir du thread Dispatcher, sinon l'interface utilisateur va exploser. Lorsque vous faites cela, vous êtes soit dans une méthode sur ce fil déjà ou (espérons-le plus probable) Vous êtes dans un fil d'arrière-plan et en utilisant Dispatcher.begininvoke pour ajouter l'élément.

Lorsque vous lancez la mise à jour sur le répartiteur, utilisez Dispatcherity.normal comme priorité. Le répartiteur a une file d'attente d'éléments de travail et de votre normal poussera (peut-être étonnamment) haut dans cette file d'attente.

Le bit du code que WPF fonctionne pour mettre à jour une liaison de données lorsque les données sous-jacentes ont modifié des exécutions à DispatcherPriority.databind , ce qui est inférieur à normal . Cela signifie que la liaison de données ne sera généralement pas mise à jour jusqu'à ce que tous vos éléments soient ajoutés (ou alternativement, si vos articles prennent beaucoup de temps à ajouter, cela pourrait se produire lorsque le répartiteur est inactif entre l'ajout d'éléments).

Le bit du code qui rend votre contrôle (disons, lorsque ses signaux de liaison une mise à jour) s'exécute à DispatcherPerity.Render et est une priorité inférieure à celle de la liaison. Cela signifie que votre contrôle ne fera que lorsque le répartiteur est à court de liaisons à mettre à jour, ce qui ne se produira à son tour que lorsque le répartiteur est à court d'éléments - ajoute des ajouts au processus.

Si cela sonne étrange, rappelez-vous que chaque couche (mise à jour - roulement) provoque l'installation d'un drapeau métaphorique sur le calque ci-dessous - vous n'obtenez pas dix liaisons puis dix rendez-vous. Si votre article ajoute est rapide, vous obtiendrez tous vos ajouts suivis d'une liaison et d'un rendu - ce qui est parfait.

Fondamentalement: Si vous utilisez le répartiteur comme prévu, vous n'avez rien à craindre. Il semble "faux" d'avoir rendu comme une priorité relativement faible sur le répartiteur, mais en fait, c'est très intelligent: -)


0 commentaires

4
votes

Voir que vous travaillez avec de grandes listes, vous souhaiterez peut-être consulter la virtualisation de l'UI WPF. Voici une bonne série de poteaux de blogs à ce sujet:

http://blogs.msdn.com/dancre/archive /tags/virtualizingtilepanel/default.aspx

Normalement, vous seriez des éléments à la collection et que vous avez cette collection PataNTound à une liste de contrôle de la liste. La liste de liste, si elle est faite correctement, ne doit pas rafraîchir les éléments qui sont ajoutés et ne sont pas visibles.


0 commentaires