2010-05-10 5 views
0

Voici un cinario:WPF: Comment GARDER la même instance ItemTemplate une fois créée?

J'ai un ListView, avec ItemsSource = ProjectModel.Instance.PagesModelsCollection; où PagesModelsCollection est un ObservableCollection

Dans la partie XAML ListView:

<ListView.ItemTemplate> 

      <DataTemplate x:Name="PagesViewDataTemplate"> 
       <DataTemplate.Resources> 
        <Style x:Key="PageHostStyle" TargetType="{x:Type p:KPage}"> 
        </Style> 
       </DataTemplate.Resources> 
       <StackPanel x:Name="MarginStack" Margin="50,50,50,50" > 
       <p:KPage x:Name="PageHost" > 
       </p:KPage> 
       </StackPanel> 
       </DataTemplate> 
</ListView.ItemTemplate> 

Le problème est ItemTemplate est recréé chaque fois que nous réactualiser cette liste. Donc, si nous avons 100 éléments dans l'affichage de la liste, une autre 100 nouvelle instance de ItemTemplate sera créée si nous actualisons les éléments! En conséquence, si nous ajoutons UIElements sur l'une des intentes ItemTemplate, ces UIElements ajoutés seront perdus, car l'ancien ITemTemplate est remplacé par un nouveau!

Comment puis-je GARDER l'instance ItemTemplate une fois qu'elle est créée ??

Répondre

0

Samir,

Ce sont les travaux de liaison façon - si vous liez de nouveaux éléments, les anciens sont perdus. Mais si vous voulez être plus malin, vous pouvez utiliser une liste générique, plutôt que ObservableCollection, et implémenter INotifyPropertyChanged dans une classe contenant cette collection (votre DataContext) pour lier les éléments de la liste juste quand vous le voulez. Par exemple:

#region INotifyPropertyChanged Members 

public event PropertyChangedEventHandler PropertyChanged; 

public void OnPropertyChanged(string propertyName) 
{ 
    PropertyChangedEventHandler handler = this.PropertyChanged; 

    if (handler != null) 
     handler(this, new PropertyChangedEventArgs(propertyName)); 
} 

#endregion 

Et puis, quand vous voulez relier les éléments, vous pouvez simple appel quelque chose comme ceci:

//when your collection changes and you're sure you want to rebind it: 
OnPropertyChanges("YourCollectionName"); 

Cela rebind tous les éléments lorsque vous en avez besoin, et non pas en cas de changement de collecte.

1

Ce n'est pas un problème avec votre modèle - c'est un problème avec la façon dont vos données sont liées à votre contrôle de liste.

ObservableCollection est une collection qui implémente l'interface INotifyCollectionChanged. Cette interface déclenche des événements lorsque des éléments sont ajoutés ou supprimés de votre collection et permet en fait à d'éviter le scénario que vous voyez.

Dans votre code, recréez-vous la collection chaque fois qu'elle change ou ajoutez-vous simplement des éléments à la collection existante? Mon soupçon est que vous faites le premier, c'est pourquoi vous verrez le comportement que vous décrivez (même si les objets de la collection sont les mêmes, la collection elle-même est différente).

(La solution de Piotr fera toujours recréer toutes vos commandes chaque fois que vous vous reconnecterez - cela signifie simplement que vous devrez initier la reliure, ce que je qualifierais de code moins élégant et moins intuitif.)

+0

Merci pour la réponse, je ne suis pas re-créer la collection, mais, j'ai remarqué que l'actualisation des éléments de la vue de liste entraîne la recréation des modèles d'élément. –

+0

Que voulez-vous dire "rafraîchir les articles?" Si vous détruisez et recréer les éléments de la collection, cela a à peu près le même effet: le modèle de données de chaque élément est recréé. –

Questions connexes