DataTemplating用于嵌套ObservableCollections的数据绑定

时间:2012-03-29 11:43:05

标签: wpf listview data-binding

我正在尝试创建一个ListView控件,该控件通过绑定到ObservableCollection来填充,ObservableCollection本身包含另一个ObservableCollection,我需要在ListView中显示数据。

澄清我有一个对象层次结构如下:

ClassA
{
    int ID = 123;
    string Name = "Value";
}

ClassB
{
    int ID = 456;
    ObservableCollection<ClassA> CollectionOfClassA;
}

ClassC
{
    int ID = 789;
    ObservableCollection<ClassB> CollectionOfClassB;
}

从这里我想得到以下ListView布局:

(ClassC.CollectionOfClassB ListView)
+-------------+-------------+------------------+--------------------------------+
|  ClassB.ID  |  CollectionOfClassA.ClassA.ID  |  CollectionOfClassA.ClassA.ID  |
+-------------+-------------+------------------+--------------------------------+
|  ClassB.ID  |  CollectionOfClassA.ClassA.ID  |  CollectionOfClassA.ClassA.ID  |
+-------------+-------------+------------------+--------------------------------+

为了实现这一点,我假设我需要将ListView绑定到我的CollectionOfClassB集合,但是,datatemplate结构和后续生成行的绑定让我有点难过。

有人可以帮我解决这个问题吗?

非常感谢,

修改

上表中的第一列引用了ClassC.CollectionOfClassB集合中索引对象的ID字段,每一行都是存储在CollectionOfClassB中的单个对象。

存储在CollectionOfClassB中的每个ClassB对象都有自己的CollectionOfClassA,我试图将它放在listview中与其父对象相同的行上。 CollectionOfClassA中的每个ClassA对象都是一列。

编辑2:

第一列由ClassB中的ID字段填充CollectionOfClassB中的当前项,后续列使用CollectionOfClassA中每个项的数据填充。列标题是ClassA.ID,而内容例如是ClassA.Name。

我正在寻找能够实现这一目标的XAML标记示例。

1 个答案:

答案 0 :(得分:1)

如果你知道ClassB.CollectionOfClassA总是相同的长度,你可以绑定到它的索引值

这是一个粗略的例子

<!-- Assumes DataContext is ClassC -->
<ListView ItemsSource="{Binding CollectionOfClassB}">
    <ListView.View>
        <GridView>
            <GridViewColumn DisplayMemberBinding="{Binding Id}" Header="ClassB.Id" />
            <GridViewColumn DisplayMemberBinding="{Binding CollectionOfClassA[0].Id}" Header="ClassA[0].Id" />
            <GridViewColumn DisplayMemberBinding="{Binding CollectionOfClassA[1].Id}" Header="ClassA[1].Id" />
        </GridView>
    </ListView.View>
</ListView>

如果您有动态的列数,则会变得有点棘手

最简单的方法是使用自定义列并以水平StackPanel

之类的方式显示项目
<!-- Assumes DataContext is ClassC -->
<ListView ItemsSource="{Binding CollectionOfClassB}">
    <ListView.View>
        <GridView>
            <GridViewColumn DisplayMemberBinding="{Binding Id}" Header="ClassB.Id" />
            <GridViewColumn Header="CollectionOfA"
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <ItemsControl ItemsSource="{Binding CollectionOfClassA}">
                            <ItemsControl.ItemsPanelTemplate>
                                <StackPanel Orientation="Horizontal" />
                            </ItemsControl.ItemsPanelTemplate>

                            <ItemsControl.ItemTemplate>
                                <TextBlock Text="{Binding Id}" Width="50" />
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
        </GridView>
    </ListView.View>
</ListView>

当然,这不使用像排序

这样的内置GridView功能