2009-09-18 3 views
1

У меня есть TreeView, который создает все его элементы из привязки данных ObservableCollections. У меня есть иерархия объектов GameNode, каждый объект имеет два ObservableCollections. Одна коллекция имеет объекты EntityAttrib, а другая - объекты GameNode. Можно сказать, что объект GameNode представляет папки, а EntityAttrib представляет файлы. Чтобы отобразить оба атрибута и GameNodes в том же TreeView, я использую Multibinding. Все это отлично работает при запуске, но когда я добавляю новый GameNode где-то в иерархии, TreeView не обновляется. Я установил точку останова в моем методе конвертера, но он не вызывается при добавлении нового GameNode. Кажется, что ObservableCollection не уведомляет MultiBinding об изменении. Если я закомментирую MultiBinding и привяжу только к коллекции GameNode, она работает так, как ожидалось.ObservableCollection не обновляет Multibinding в C# WPF

XAML:

<HierarchicalDataTemplate DataType="{x:Type local:GameNode}"> 
     <HierarchicalDataTemplate.ItemsSource> 
      <MultiBinding Converter="{StaticResource combineConverter}"> 
       <Binding Path="Attributes" /> 
       <Binding Path="ChildNodes" /> 
      </MultiBinding> 
     </HierarchicalDataTemplate.ItemsSource> 
     <TextBlock Text="{Binding Path=Name}" ContextMenu="{StaticResource EntityCtxMenu}"/> 
    </HierarchicalDataTemplate> 

C#:

public class GameNode 
{ 
    string mName; 
    public string Name { get { return mName; } set { mName = value; } } 

    GameNodeList mChildNodes = new GameNodeList(); 
    public GameNodeList ChildNodes { get { return mChildNodes; } set { mChildNodes = value; } } 

    ObservableCollection<EntityAttrib> mAttributes = new ObservableCollection<EntityAttrib>(); 
    public ObservableCollection<EntityAttrib> Attributes { get { return mAttributes; } set { mAttributes = value; } } 
} 

GameNodeList является подклассы ObservableCollection

ответ

1

Лучший способ сделать (только если EntityAttrib и GameNode два разных классов, унаследованных от этого же базовый класс) будет фактически определять два шаблона данных, как показано ниже.

<HierarchicalDataTemplate DataType="{x:Type local:GameNode}">   

<HierarchicalDataTemplate DataType="{x:Type local:EntityAttrib}">   

Это лучше, потому что его легче вспомнить позже. Рассмотрим объекты файловой системы, как классы FileInfo, так и DirectoryInfo фактически получены из класса FileSystemInfo, который имеет общее свойство.

У вас должен быть базовый класс «BaseGameNode», есть что-то в нем, «GameNode» и «GameEntityAttribNode», оба получены из «BaseGameNode». И они должны иметь только одно свойство «Дети», которое является наблюдаемой коллекцией типа BaseGameNode, но его экземпляр элемента должен быть различным по мере необходимости.

Вы можете определить несколько шаблонов при условии, что им есть что отличить, тип будет автоматически выбран для дочерних узлов узла.

Значение, которое вы связали, не будет обновляться, потому что они не являются имуществом зависимостей, и они не уведомляются об изменениях. Поскольку multibinding не будет обнаруживать событие изменения коллекции вообще, если не будет изменен ссылочный/экземпляр коллекции. Когда вы меняете элемент в коллекции, ваш фактический экземпляр атрибутов/свойств остается таким же.

Когда вы связываете ItemsSource = collection, его ItemSource, который будет прослушивать событие CollectionChange и соответствующим образом обновлять элементы.

+0

Я не понимаю, как это помогает. У меня все еще будет такая же проблема с многосвязным. У меня на самом деле есть HierarchicalDataTemplate для типа EntityAttrib, чтобы отображать их в другом цвете. – 2009-09-18 08:49:06

+0

Ваш конвертер не будет вызываться в 2 раза вообще, потому что он будет вызываться только при создании узла. Поскольку ваш multibinding не будет обнаруживать изменения внутри наблюдаемой коллекции, но ее ItemSource, который обнаружит изменение коллекции и обновление. –

+0

Может быть, я глуп, но я этого не понимаю. Я ничего не меняю в GameNode, я добавляю GameNode в коллекцию, поэтому коллекция изменяется и должна отправлять событие. Вы сказали, что ItemsSource прослушивает CollectionChange, но ItemsSource - это MultiBind, который, в свою очередь, является коллекциями. – 2009-09-18 10:04:48

Смежные вопросы