2010-01-26 12 views
8

Niestety - moje pytanie jest prawie identyczne z this one, ale ponieważ nie otrzymałem realnej odpowiedzi, mam nadzieję, że ktoś inny ma jakieś świeże pomysły.Drzewo TreeView WPF jest przenoszone do ObservableCollection nie aktualizuje węzłów głównych

Mam TreeView WPF, który jest związany z hierarchii jednego typu:

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

Klasa Entity implementuje INotifyPropertyChanged, ale pominięto ten kod dla jasności.

TreeView jest związana ObservableCollection < Entity> i każdorazowo Entity ujawnia zestaw zawartych przypadkach Entity poprzez jego właściwości dzieci:

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

Początkowo TreeView wiąże się prawidłowo i prawidłowo wyświetlany wielopoziomowe hierarchia. Ponadto, gdy członkostwo w jednej z kolekcji dzieci zostanie zmodyfikowane programowo, zmiany zostaną poprawnie odzwierciedlone w TreeView.

Jednak zmiany w członkostwie na poziomie członków root ObservableCollection < Entity> nie są odzwierciedlane w TreeView.

Wszelkie sugestie będą mile widziane.

Dzięki, Tim

Odpowiedz

19

Moje pierwsze przypuszczenie, że masz coś jak następuje do węzła głównego:

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

Następnie, zamiast robić coś [dobre], jak następuje:

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

robisz coś [złe] tak:

Entities = new ObservableCollection<Entity>(someSetOfItems); 

powinien być w stanie wyśledzić ten problem poprzez pole podkładową nieruchomości Podmioty readonly:

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

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

Dzięki - genialna analiza! –

+1

Wow, to działało dla mnie. Dlaczego ta zmiana działa? –

+3

@Mike W przykładzie [Bad] tworzy nową jednostkę, przerywając w ten sposób powiązanie z oryginałem. W [dobrym] przykładzie on po prostu oczyszcza i dodaje elementy do niego, ale zachowuje oryginalną kolekcję. –

2

dalszych wyjaśnień, długo na odpowiedź przyjść, ale wierzę, że jeśli wiązanie w XAML, a następnie w kodzie, przypisz nowy obiekt do właściwości, przerwij wiązanie, więc będziesz musiał powtórzyć powiązanie w kodzie, aby działał. Stąd rozwiązanie z polem tylko do odczytu. Jeśli tak postąpisz, nie będziesz mógł przypisać nowej ObservableCollection i nie złamiesz powiązania, przypisując nowy obiekt do pola wsparcia.