Treeview转换器问题

时间:2011-12-09 15:59:26

标签: .net wpf treeview ivalueconverter

我有一个绑定到集合的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时,转换器未被调用以在树层次结构中显示相同

1 个答案:

答案 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作为其源{。}}。