将字典 <string, DataTable> 绑定到 ItemsControl 无效
Binding Dictionary<string, DataTable> to ItemsControl not working
当列表中的字典项展开时,我需要显示字典中的每个数据表(值)。字典项的键应该是扩展符header。视图模型正确填充数据,但 UI 上没有显示任何内容。如何获取要显示在 UI 上的数据表列表
到目前为止,这就是我所拥有的:
<!-- Data grid template -->
<DataTemplate x:Key="ValuesTemplate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="data grid header text" Margin="20,0,0,0" Grid.Row="2"/>
<DataGrid ItemsSource="{Binding Value[0]}"/>
</Grid>
</DataTemplate>
<!-- List of data tables -->
<ItemsControl ItemsSource="{Binding myDictionary}" VirtualizingStackPanel.IsVirtualizing="True">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Expander IsExpanded="True" Margin="0,0,0,10">
<Expander.Header>
<TextBlock Text="{Binding Key}" Margin="0,0,20,0" VerticalAlignment="Top"/>
</Expander.Header>
<ContentControl Content="{Binding}" ContentTemplate="{StaticResource ValuesTemplate}" ScrollViewer.CanContentScroll="True" Margin="20,0,0,0"/>
</Expander>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
在 WPF 中,ItemsControl.ItemsSource
可以绑定到实现 IEnumerable
的任何类型。那么,Dictionary<TKey, TValue>
是如何用 IEnumerable
表示的呢?它作为 IEnumerable<KeyValuePair<TKey, TValue>>
.
这样做
因此,您可以忽略拥有字典这一事实,而是将其视为 KeyValuePair<TKey, TValue>
个对象的枚举。
现在,您已经实现了主要部分大部分 正确。您有一个 ItemsControl
,正确绑定,并且您正在对每个项目应用 DataTemplate
。但是,请记住每个项目都是 KeyValuePair
。因此,TextBlock.Text
属性 已正确绑定到 Key 属性,但内容已绑定到项目(KeyValuePair<TKey, TValue
) 本身。这可能是故意的,但我的猜测是您可能希望将 ContentControl 绑定到 Value 属性。
第二部分是您要对原始 DataTemplate
中的每个 Content
应用 ContentTemplate
。我看到至少一个,也许是两个潜在的错误:
- 您
ValuesTemplate
似乎是在假设内容是 DataTable
类型的情况下工作,而实际上它是 KeyValuePair<string, DataTable>
类型。在这种情况下,我会将 Content
绑定到 Value 属性.
- 您
ValuesTempalte
似乎也将 DataGrid.ItemsSource
绑定到 Values[0]
。我在这里的假设是,您再次认为您的内容是 DataTable
的一种类型,但实际上不是,即使是这种情况,为什么将 ItemsSource
绑定到 DataTable
?您的 DataTable
是否由行组成,每一行本身就是一个序列?我猜你只是想做 <DataGrid ItemsSource="{Binding}" />
.
TL;DR;
<!-- Data grid template -->
<DataTemplate x:Key="ValuesTemplate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="data grid header text" Margin="20,0,0,0" Grid.Row="2" />
<DataGrid ItemsSource="{Binding}" />
</Grid>
</DataTemplate>
<!-- List of data tables -->
<ItemsControl ItemsSource="{Binding MyDictionary}" VirtualizingStackPanel.IsVirtualizing="True">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Expander IsExpanded="True" Margin="0,0,0,10">
<Expander.Header>
<TextBlock Text="{Binding Key}" Margin="0,0,20,0" VerticalAlignment="Top" />
</Expander.Header>
<ContentControl Content="{Binding Value}" ContentTemplate="{StaticResource ValuesTemplate}" ScrollViewer.CanContentScroll="True" Margin="20,0,0,0" />
</Expander>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
当列表中的字典项展开时,我需要显示字典中的每个数据表(值)。字典项的键应该是扩展符header。视图模型正确填充数据,但 UI 上没有显示任何内容。如何获取要显示在 UI 上的数据表列表 到目前为止,这就是我所拥有的:
<!-- Data grid template -->
<DataTemplate x:Key="ValuesTemplate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="data grid header text" Margin="20,0,0,0" Grid.Row="2"/>
<DataGrid ItemsSource="{Binding Value[0]}"/>
</Grid>
</DataTemplate>
<!-- List of data tables -->
<ItemsControl ItemsSource="{Binding myDictionary}" VirtualizingStackPanel.IsVirtualizing="True">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Expander IsExpanded="True" Margin="0,0,0,10">
<Expander.Header>
<TextBlock Text="{Binding Key}" Margin="0,0,20,0" VerticalAlignment="Top"/>
</Expander.Header>
<ContentControl Content="{Binding}" ContentTemplate="{StaticResource ValuesTemplate}" ScrollViewer.CanContentScroll="True" Margin="20,0,0,0"/>
</Expander>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
在 WPF 中,ItemsControl.ItemsSource
可以绑定到实现 IEnumerable
的任何类型。那么,Dictionary<TKey, TValue>
是如何用 IEnumerable
表示的呢?它作为 IEnumerable<KeyValuePair<TKey, TValue>>
.
因此,您可以忽略拥有字典这一事实,而是将其视为 KeyValuePair<TKey, TValue>
个对象的枚举。
现在,您已经实现了主要部分大部分 正确。您有一个 ItemsControl
,正确绑定,并且您正在对每个项目应用 DataTemplate
。但是,请记住每个项目都是 KeyValuePair
。因此,TextBlock.Text
属性 已正确绑定到 Key 属性,但内容已绑定到项目(KeyValuePair<TKey, TValue
) 本身。这可能是故意的,但我的猜测是您可能希望将 ContentControl 绑定到 Value 属性。
第二部分是您要对原始 DataTemplate
中的每个 Content
应用 ContentTemplate
。我看到至少一个,也许是两个潜在的错误:
- 您
ValuesTemplate
似乎是在假设内容是DataTable
类型的情况下工作,而实际上它是KeyValuePair<string, DataTable>
类型。在这种情况下,我会将Content
绑定到 Value 属性. - 您
ValuesTempalte
似乎也将DataGrid.ItemsSource
绑定到Values[0]
。我在这里的假设是,您再次认为您的内容是DataTable
的一种类型,但实际上不是,即使是这种情况,为什么将ItemsSource
绑定到DataTable
?您的DataTable
是否由行组成,每一行本身就是一个序列?我猜你只是想做<DataGrid ItemsSource="{Binding}" />
.
TL;DR;
<!-- Data grid template -->
<DataTemplate x:Key="ValuesTemplate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="data grid header text" Margin="20,0,0,0" Grid.Row="2" />
<DataGrid ItemsSource="{Binding}" />
</Grid>
</DataTemplate>
<!-- List of data tables -->
<ItemsControl ItemsSource="{Binding MyDictionary}" VirtualizingStackPanel.IsVirtualizing="True">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Expander IsExpanded="True" Margin="0,0,0,10">
<Expander.Header>
<TextBlock Text="{Binding Key}" Margin="0,0,20,0" VerticalAlignment="Top" />
</Expander.Header>
<ContentControl Content="{Binding Value}" ContentTemplate="{StaticResource ValuesTemplate}" ScrollViewer.CanContentScroll="True" Margin="20,0,0,0" />
</Expander>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>