编辑:为了有效展平,CompositeCollection
对我来说非常有用。
我会使用value converter,那么你的绑定源可以保持不变。
编辑:转换器可能会看起来像这样(未经测试!):
[ValueConversion(typeof(ObservableCollection<Node>), typeof(List<Node>))]
public class ObservableCollectionToListConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
ObservableCollection<Node> input = (ObservableCollection<Node>)value;
int targetLevel = int.Parse(parameter as string);
List<Node> output = new List<Node>();
foreach (Node node in input)
{
List<Node> tempNodes = new List<Node>();
for (int level = 0; level < targetLevel; level++)
{
Node[] tempNodesArray = tempNodes.ToArray();
tempNodes.Clear();
foreach (Node subnode in tempNodesArray)
{
if (subnode.Children != null) tempNodes.AddRange(subnode.Children);
}
}
output.AddRange(tempNodes);
}
return output;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
}
你会在XAML中使用这样的:
<Window.Resources>
...
<local:ObservableCollectionToListConverter x:Key="ObservableCollectionToListConverter"/>
</Window.Resources>
...
<ListView ItemsSource="{Binding MyNodes, Converter={StaticResource ObservableCollectionToListConverter}, ConverterParameter=3}">
(ConverterParameter
指定级别)
与其他两个相同的问题,通过创建副本,我怎么知道何时创建副本,每次添加或删除节点?那么当添加1000个节点时,绑定将被更新1000次,调用转换器1000次,创建所有节点的新副本999不必要的时间 – markmnl 2011-02-17 01:07:21
那么,我个人不会处理这些问题,直到它实际上*成为一个问题的表现。你可以添加一个布尔属性到转换器打开或关闭。我怀疑有没有更简单的方法来做这样的事情,你可能可以改进某些领域,但最终你的产品将永远是一个由合并列表组成的列表。 – 2011-02-17 01:34:52
对不起,但是创建了一个999次列表的新副本,并且仅当添加1000个项目并且仅使用创建的第1000个副本时才会处理该副本是不可接受的 - 我可以有超过1000个项目。打开和关闭转换器不是一种选择,因为我不知道可能要添加多少物品。顺便说一下,我倾向于仅使用转换器设计的转换器:在不同类型的目标和源之间转换对象,如果从方法填充,最好使用ObjectDataProvider。 – markmnl 2011-02-17 02:07:41