WPF HierarchicalDataTemplate doesn't update It

2019-06-25 08:21发布

Here is some XAML

<HierarchicalDataTemplate DataType="{x:Type data:FolderEntity}" 
  ItemsSource="{Binding Path=FolderEntities,UpdateSourceTrigger=PropertyChanged}">
  <Label Content="{Binding FolderName}"/>
</HierarchicalDataTemplate>
<TreeView/>

data:FolderEntity is a LINQ to SQL data class which implements the INotifyPropertyChanging and INotifyPropertyChanged interfaces.

My problem is that when I change the FolderEntities property the binding doesn't update. If I change the FolderName property the tree node that corresponds to that item will change, but the collection that is FolderEntities just wont.

I'm thinking WPF checks to see whether the collection reference has changed, or does the ItemsSource object have to be an ObservableCollection`1 for this to work?

Any input on the matter is much appreciated.

3条回答
我命由我不由天
2楼-- · 2019-06-25 08:50

Yes, the underlying collection (FolderEntities) will need to be an ObservableCollection<T> for the HierarchicalDataTemplate to be notified of the changes. Either that or a collection that implements INotifyCollectionChanged.

查看更多
Viruses.
3楼-- · 2019-06-25 08:52

This is how I got it to work, thanks Matt!

public abstract class ObservableHierarchy<T>
{
    public T Current { get; set; }

    public ObservableCollection<ObservableHierarchy<T>> Children { get; set; }

    public ObservableHierarchy( T current, Func<T, IEnumerable<T>> expand )
    {
        this.Current = current;
        this.Children = new ObservableCollection<ObservableHierarchy<T>>();
        foreach ( var item in expand( current ) )
        {
            Children.Add( Create( item ) );
        }
    }

    protected abstract ObservableHierarchy<T> Create( T item );
}

Then I specialize that base class to whatever data class I'm currently using.

public class ObservableFolderHierarchy:
    ObservableHierarchy<FolderEntity>
{
    public ObservableFolderHierarchy( FolderEntity root )
        : base( root, x => x.FolderEntities )
    {
    }

    protected override ObservableHierarchy<FolderEntity> Create( FolderEntity item )
    {
        return new ObservableFolderHierarchy( item );
    }
}

Slightly modified XAML and it works just great! Changes to the collection or properties of Current updates the TreeView accordingly.

<HierarchicalDataTemplate DataType="{x:Type ui:ObservableFolderHierarchy}"
 ItemsSource="{Binding Children}">
 <StackPanel Orientation="Horizontal">
  <Image Source="/UI/Resources/folder.png" Width="16" Height="16"/>
  <TextBlock Text="{Binding Current.FolderName}"/>
 </StackPanel>
</HierarchicalDataTemplate>
查看更多
倾城 Initia
4楼-- · 2019-06-25 09:01

Matt is correct. For the data binding engine to be notified of a change within a collection it need to bind to an ObservableCollection.

What you were binding to was the property and PropertyChanged (from INotifyPropertyChanged) was only being called when the property was being set e.g. FolderEntities = aNewValue; the binding engine was unaware of any changes that occurred within the collection.

查看更多
登录 后发表回答