绑定到ObservableCollection并使用ValueConverter

本文关键字:ValueConverter ObservableCollection 绑定 | 更新日期: 2023-09-27 18:06:01

我试图通过ValueConverterObservableCollection<T>绑定到TreeView(或任何其他控件)。在ValueConverter中,我使用AsHierarchy扩展(scip.be)将自引用(每个实体都有一个ParentId字段)转换为层次结构。

如前所述,我将实体(平面列表)存储在ObservableCollection<T>中,当我不使用ValueConverter时,对列表的更新会反映在视图(GUI)上。

如果我添加ValueConverter,更新不再反映在我的视图上,如果我在值转换器内设置一个断点,我注意到它只在加载时调用一次,忽略所有进一步的CollectionChanged事件。

ValueConverter的源代码:

public class HierarchyValueConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null) return null;
        ObservableCollection<Entity> data = (ObservableCollection<Entity>)value;
        return data.AsHierarchy(p => p.Id, p => p.ParentId);
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

绑定转换器的ItemsSource:

ItemsSource="{Binding Data,
                      Source={StaticResource MyDataSource},
                      Converter={StaticResource HierarchyValueConverter}}"

我希望有人能提供一个答案,因为这个问题已经困扰我很长一段时间了。

提前感谢!

绑定到ObservableCollection<T>并使用ValueConverter

以一种可观察的方式绑定一个层次结构几乎肯定不能通过一个扩展方法来解决。

我建议你实现自己的实用程序类,像CompositeCollection一样,但当然是针对分层设置,如果添加一个项目,重建整个树将很快变得不可行的。这可能不是一个微不足道的任务,但这是我建议的总体方向。

ObservableCollection实现接口INotifyCollectionChanged,它通知你的itemscontrol发生了一些变化。AsHierarchy只是返回一个IEnumerable,它不提供更改通知,因此你将不再看到更新。

快速而肮脏的修复是订阅ObservableCollection的CollectionChanged事件。在事件处理程序中,强制重新绑定,以便值转换器的Convert方法再次运行。