我有一个绑定到集合的wpf树视图。模型集合的类型为:
public Class A {
public string Name {get; set}
public ObservableCollection< B> Bs {get; set;}
}
public Class B {
public ObservableCollection< C> Cs {get; set;}
}
public Class C {
public string Name {get; set;}
}
XAML:
<my:AConverter x:Key="AConverter"/>
<DataTemplate DataType="{x:Type C}">
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
<HierarchicalDataTemplate DataType="{x:Type A}"
ItemsSource="{Binding Converter={StaticResource AConverter}}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
<treeView Grid.Row="0" ItemsSource="{Binding As}"/>
AConverter.cs:
public class AConverter: IValueConverter {
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
if (value is A) {
return (value as A).Bs.SelectMany(b => b.Cs);
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
throw new NotImplementedException();
}
}
预期的输出是:树视图中的A-> C而不是B.这里的问题是当我们添加新的C时,转换器未被调用以在树层次结构中显示相同
答案 0 :(得分:0)
如果您应用的转换器未返回observable collection [原文] ,则会丢失更新。你试图实现的是真的有点痛苦,基本上你需要在保持更新的同时展平层次结构,这可以在某种程度上使用CompositeCollection
来完成。 e.g。
public class AConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var compositeCollection = new CompositeCollection();
var a = (A)value;
// React to changes of the Bs:
a.Bs.CollectionChanged += (s, e) =>
{
switch (e.Action)
{
case System.Collections.Specialized.NotifyCollectionChangedAction.Add:
// ObservableCollection only ever manipulates one item, thus NewItems[0].
compositeCollection.Insert(e.NewStartingIndex, new CollectionContainer { Collection = ((B)e.NewItems[0]).Cs });
break;
case System.Collections.Specialized.NotifyCollectionChangedAction.Move:
//TODO: Implement
break;
case System.Collections.Specialized.NotifyCollectionChangedAction.Remove:
//TODO: Implement
break;
case System.Collections.Specialized.NotifyCollectionChangedAction.Replace:
//TODO: Implement
break;
case System.Collections.Specialized.NotifyCollectionChangedAction.Reset:
//TODO: Implement
break;
default:
break;
}
};
// Add the items for the current Bs:
foreach (var item in a.Bs)
{
compositeCollection.Add(new CollectionContainer { Collection = item.Cs });
}
return compositeCollection;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
}
其他案例的实施取决于您,插入似乎有效。
更好的解决方案可能是在每个级别公开CompositeCollections
,因为它们可以很容易地嵌套,即您可以添加CollectionContainer
作为其源{。}}。