2010-01-26 20 views
8

Désolé - ma question est presque identique à this one mais étant donné qu'il n'a pas reçu une réponse viable, j'espère que quelqu'un d'autre a des idées nouvelles.WPF TreeView lié à ObservableCollection pas mettre à jour les noeuds racine

J'ai un TreeView WPF qui est lié à une hiérarchie d'un seul type:

public class Entity 
{ 
    public string Title { get; set; } 
    public ObservableCollection<Entity> Children { get; set; } 
} 

La classe entité implémente INotifyPropertyChanged, mais j'ai omis ce code pour plus de clarté.

Le TreeView est lié à un ObservableCollection < Entité> et chaque instance d'entité expose un ensemble d'instances contenues entité via sa propriété Enfants:

<TreeView ItemsSource="{Binding Path=Entities}"> 
    <TreeView.Resources> 
     <HierarchicalDataTemplate DataType="{x:Type local:Entity}" ItemsSource="{Binding Path=Children}"> 
      <TextBlock Text="{Binding Path=Title}" /> 
     </HierarchicalDataTemplate> 
    </TreeView.Resources> 
</TreeView> 

Au départ, le TreeView se fixe comme prévu et affiche correctement un multi-niveaux hiérarchie. En outre, lorsque l'appartenance à l'une des collections enfants est modifiée par programme, les modifications sont correctement répercutées dans TreeView. Cependant, les modifications apportées à l'appartenance du niveau membre ObservableCollection < Entity> ne sont pas reflétées dans TreeView.

Toutes les suggestions seraient appréciées.

Merci, Tim

Répondre

19

Mon estimation initiale est que vous avez quelque chose comme ce qui suit pour le nœud racine:

public ObservableCollection<Entity> Entities 
{ 
    get; 
    set; 
} 

Puis, au lieu de faire quelque chose [bon] comme ce qui suit:

Entities.Clear(); 
foreach (var item in someSetOfItems) 
    Entities.Add(item); 

Vous faites quelque chose [mauvais] comme ceci:

Entities = new ObservableCollection<Entity>(someSetOfItems); 

Vous devriez être en mesure de traquer la question en faisant le domaine de soutien de la propriété des entités readonly:

private readonly ObservableCollection<Entity> _entities 
    = new ObservableCollection<Entity>(); 

public ObservableCollection<Entity> Entities 
{ 
    get 
    { 
     return _entities; 
    } 
} 
+0

Merci - une analyse brillante! –

+1

Wow, cela a fonctionné pour moi. Pourquoi ce changement fonctionne-t-il? –

+3

Dans l'exemple @ Mike [Bad], il crée une nouvelle entité, rompant ainsi la liaison à l'original. Dans le [bon] exemple, il est en train d'effacer et d'ajouter des éléments mais en conservant la collection originale. –

2

explication De plus, beaucoup de temps pour répondre à venir, mais je crois que si vous faites la liaison en XAML, puis dans le code attribuer un nouvel objet à la propriété que vous cassez la liaison, de sorte que vous devrez refaire la liaison dans le code pour que cela fonctionne. D'où la solution avec le champ de support en lecture seule. Si vous le faites comme ça, vous ne serez pas en mesure d'attribuer une nouvelle ObservableCollection et vous ne cassera pas la liaison en attribuant un nouvel objet dans le champ de support.