【问题标题】:Binding Dictionary<string, DataTable> to ItemsControl not working将 Dictionary<string, DataTable> 绑定到 ItemsControl 不起作用
【发布时间】:2016-11-02 21:56:19
【问题描述】:

当列表中的字典项展开时,我需要显示字典中的每个数据表(值)。并且字典项的键应该是扩展器标题。视图模型正确填充数据,但 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>

【问题讨论】:

    标签: c# wpf dictionary binding itemscontrol


    【解决方案1】:

    在 WPF 中,ItemsControl.ItemsSource 可以绑定到任何实现 IEnumerable 的类型。那么,Dictionary&lt;TKey, TValue&gt; 是如何用IEnumerable 表示的呢?它以IEnumerable&lt;KeyValuePair&lt;TKey, TValue&gt;&gt; 的形式这样做。

    因此,您可以忽略您拥有字典这一事实,而将其视为KeyValuePair&lt;TKey, TValue&gt; 对象的枚举。


    现在,您的主要部分实现大部分正确。您有一个ItemsControl,正确绑定,并且您正在将DataTemplate 应用于每个项目。但是,请记住,每个项目都是KeyValuePair。因此,TextBlock.Text 属性被正确绑定到 Key 属性,但内容被绑定到项目 (KeyValuePair&lt;TKey, TValue) 本身。这可能是故意的,但我猜您可能希望 ContentControl 绑定到 Value 属性。

    第二部分是您希望将ContentTemplate 应用于原始DataTemplate 中的每个Content。我至少看到了一个,也许是两个潜在的错误:

    1. ValuesTemplate 似乎是在假设内容是DataTable 的类型的情况下工作的,而实际上它是KeyValuePair&lt;string, DataTable&gt; 的类型。在这种情况下,我会将 Content 绑定到 Value 属性。
    2. 你是ValuesTempalte 似乎也将DataGrid.ItemsSource 绑定到Values[0]。我在这里的假设是,再次,您认为您的内容是DataTable 的类型,而实际上不是,即使是这种情况,为什么要将ItemsSource 绑定到DataTable 的第一行?您的DataTable 是否由行组成,每行本身都是一个序列?我猜你只是想做&lt;DataGrid ItemsSource="{Binding}" /&gt;

    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>
    

    【讨论】:

    • 谢谢。我的意图是将 Value 属性绑定到数据网格的项目源。但似乎我弄错了。我尝试了你的建议,但文本块和网格都没有出现。有什么我想念的吗?
    • 只要确保,如果您使用了@m-y 的代码,您就更正了他所做的绑定,对吗?他使用了 ItemsSource="{Binding MyDictionary}",而你有 ItemsSource="{Binding myDictionary}"
    • 两者是一样的吧? myDictionary 是键值对的列表 - List> myDictionary.
    • 我将 KeyValue 对列表更改为可观察的键值对集合,并且该键在文本块中显示为文本。但是数据表还是没有显示出来。
    • @anya:您可以将其保留为Dictionary&lt;string, DataTable&gt;,ItemsSource 会自动为您读取KeyValuePair&lt;string, DataTable&gt; 序列。
    猜你喜欢
    • 2018-08-04
    • 1970-01-01
    • 1970-01-01
    • 2012-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多