2017-01-07 1 views
-1

Je viens de trouver une énorme fuite de mémoire dans une simple application Windows Store que je développe.Pourquoi l'événement Unloaded de UserControl ne se déclencherait-il pas?

Il s'est avéré que j'ai mis un UserControl dans le ItemTemplate d'un ListView, et a accroché l'événement Unloaded du contrôle UserControl pour détacher un gestionnaire d'événements.

J'ai prévu que, lorsque les éléments de la ListView sont effacées, l'événement Unloaded du UserControl mettrait le feu, mais il ne sera pas! Mais quand je a supprimé les éléments un par un, l'événement Unloaded de l'UserControl se déclenchera comme prévu.

Quelqu'un peut-il me donner quelques conseils à ce sujet? Ou où dois-je mettre le code de nettoyage en plus de l'événement Unloaded. N'importe quelle idée est la bienvenue! THX! Voici l'extrait de code:

Pour être simplifié, le ItemTemplate de ListView est:

<DataTemplate> 
     <local:MyUserControl1 /> 
</DataTemplate> 

et MyUserControl1 est juste un UserControl vide:

public sealed partial class MyUserControl1 : UserControl 
{ 
    public MyUserControl1() 
    { 
     this.InitializeComponent(); 
     this.Unloaded += MyUserControl1_Unloaded; 
    } 

    private void MyUserControl1_Unloaded(object sender, RoutedEventArgs e) 
    { 
     Debug.WriteLine("MyUserControl1_Unloaded..."); 
    } 
} 

Répondre

1

par le ListView par défaut, il sera activer la virtualisation de l'interface utilisateur Lorsque vous appelez la méthode Clear(), le ListView fera des traitements spéciaux, il n'a pas réellement supprimé ces éléments (je crois que vous avez également trouvé cette situation).

Vous pouvez voir ActualHeight de ListView dans l'arborescence en direct (il est défini sur 0). C'est pourquoi vous ne pouvez pas voir listview sur l'interface utilisateur.

enter image description here

Ainsi la méthode solution consiste à utiliser Remove() ou listview.Itemsource=null. Vous pouvez également essayer de désactiver la virtualisation de l'interface utilisateur. Par exemple, en utilisant le StackPanel en tant que ItemsPanelTemplate.

+0

oui, vous avez raison. C'est le mécanisme conçu de la virtualisation ListView ui. Je vais continuer à utiliser la virtualisation ui et j'ai trouvé une solution pour contrôler la taille du cache. C'est mon fil sur msdn: https: //social.msdn.microsoft.com/Forums/en-US/92f76519-f139-4c94-ae5e-630f0abda66e/memory-leak-with-listview-ui-virtualization? Forum = wpdevelop – SimonFisher

+0

Le problème est toujours là. J'ai essayé les deux méthodes: 1) enlever tous les éléments un par un (au lieu d'effacer), 2) laisser listview.Itemsource = null. Il y a encore un élément conservé par ListView, dont je m'attends à ce que tous les éléments soient retirés de la mémoire. – SimonFisher

+0

@SimonFisher Je me réfère au code sur votre thread MSDN pour tester. Je ne peux pas reproduire ce problème. Lorsque j'appelle la méthode 'Effacer()', 'Remove()', les éléments sont supprimés. Je ne peux pas le trouver dans le rapport SnapShot. –