如何在 WPF 中绑定相关 table?

How to bind related table in WPF?

我有两个表,optionsitems。一项与多个选项相关联。

我想在嵌套的 ListBox 中显示项目及其选项。问题是内部 ListBoxs 不显示东西。我想也许我没有正确绑定 ItemsSource。如何绑定?

我的尝试如下:

<Window.Resources>
    <local:TaxAccessmentDataSet x:Key="taxAccessmentDataSet"/>
    <CollectionViewSource x:Key="itemsViewSource" Source="{Binding items, Source={StaticResource taxAccessmentDataSet}}"/>
    <CollectionViewSource x:Key="itemsoptionsViewSource" Source="{Binding FK_options_items, Source={StaticResource itemsViewSource}}"/>
</Window.Resources>
<ListBox x:Name="listBox"ItemsSource="{Binding}" DataContext="{StaticResource itemsViewSource}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Expander x:Name="expander" Header="{Binding name}">
                <ListBox ItemsSource="{Binding}" DataContext="{StaticResource itemsoptionsViewSource}" DisplayMemberPath="name">
                </ListBox>
            </Expander>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

一个项目的 DataContext 不再是父项目 - 它已经是您的项目。所以你必须改变

<ListBox ItemsSource="{Binding}" DataContext="{StaticResource itemsoptionsViewSource}" DisplayMemberPath="name">

<ListBox ItemsSource="{Binding items}" DisplayMemberPath="name">

这会将嵌套 ListBox 的项目绑定到 option 的 属性 items,如图所示。

内部 ListBox 的 DataContext 将是一个代表项目的 DataRowView。为了能够使用数据绑定来显示此项的相应选项,该项必须公开一个 public 属性 returns 这些选项的集合。 DataRowView class 没有,所以您不能在纯 XAML 中执行此操作。

但是您可以处理 ListBox 的 Loaded 事件并自己为选项创建一个 DataView:

<ListBox x:Name="listBox" ItemsSource="{Binding}" DataContext="{StaticResource itemsViewSource}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Expander x:Name="expander" Header="{Binding name}">
                <ListBox DisplayMemberPath="name" Loaded="ListBox_Loaded" />
            </Expander>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

private void ListBox_Loaded(object sender, RoutedEventArgs e)
{
    ListBox inner = sender as ListBox;
    if (inner != null)
    {
        DataRowView drv = inner.DataContext as DataRowView;
        if (drv != null)
        {
            DataView childView = drv.CreateChildView(drv.DataView.Table.ChildRelations[0]);
            //or drv.CreateChildView(drv.DataView.Table.ChildRelations["FK_options_items"]);
            inner.ItemsSource = childView;
        }
    }
}