2010-01-26 3 views
8

Извините, мой вопрос почти идентичен this one, но поскольку он не получил жизнеспособного ответа, я надеюсь, что у кого-то есть свежие идеи.WPF TreeView привязана к ObservableCollection, не обновляя корневые узлы

У меня есть WPF TreeView, который связан с иерархией одного типа:

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

Класс сущностей реализует INotifyPropertyChanged, но я опустил этот код для ясности.

TreeView привязан к ObservableCollection < Entity> и каждому экземпляру Entity предоставляет набор содержащихся экземпляров объекта с помощью его имущества Детей:

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

Первоначально TreeView связывается как ожидался, и корректно отображает многоуровневый иерархия. Кроме того, когда членство в одной из детских коллекций изменяется программно, изменения правильно отражаются в TreeView.

Однако изменения в членстве уровня члена корня ObservableCollection < Объект> не отображаются в TreeView.

Любые предложения будут оценены.

Спасибо, Tim

ответ

19

Моя первоначальная догадка, что у вас есть что-то вроде следующего для корневого узла:

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

Затем, вместо того, чтобы делать что-то [хороший], как следующее:

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

Вы делаете что-то [плохо], как это:

Entities = new ObservableCollection<Entity>(someSetOfItems); 

Вы должны быть в состоянии отследить проблему путем подпирая поле свойства Entities readonly:

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

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

Спасибо, гениальный анализ! –

+1

Вау, это сработало для меня. Почему это изменение работает? –

+3

@Mike В примере [Bad] он создает новую сущность, тем самым нарушая привязку к оригиналу. В [хорошем] примере он просто очищает и добавляет элементы к нему, но сохраняет исходную коллекцию. –

2

Дальнейшего объяснение, долгое время для ответа прийти, но я считаю, что если вы связывание в XAML, а затем в коде назначить новый объект для свойства, которое вы нарушаете привязку, поэтому вам придется переделать привязку в коде, чтобы он работал. Следовательно, решение с полем обратной обработки. Если вы сделаете так, вы не сможете назначить новый ObservableCollection, и вы не нарушите привязку, назначив новый объект в поле поддержки.