WPF二维数据表格/列表视图?

4

我有一个表格Item,它由3列组成:

ItemId int PK
RoomId int FK
UnitId int FK
Cost money

我希望有一个动态生成列和行的DataGrid/ListView,以显示以下数据透视表:
       Room1 Room2 Room3 Room4 
Unit1  $34   $72   $48   $98
Unit2  $64   $56   $67   $24
Unit3  $24   $34   $34   $34

我更喜欢使用控件或帮助程序而不是脏函数,因为我会经常需要此场景,但任何方案都非常受欢迎。

我想将Room1Unit1等作为行和列标题,并相应地生成/设置单元格。

1个回答

8

首先,您需要将Item对象的集合转换为适当的集合:

var dict = data.Select(i => i.UnitId).Distinct()
    .ToDictionary(u =>  u, u => data
        .Where(i => i.UnitId == u)
        .ToDictionary(d => d.RoomId, d => d));
var rooms = dict.Values.First().Keys;
DataContext = Tuple.Create(dict, rooms);

然后您需要一个带有正确的DataTemplate配置的ItemsControl

<Grid>
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
  </Grid.RowDefinitions>
  <ItemsControl ItemsSource="{Binding Item2}">
    <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate>
        <StackPanel Orientation="Horizontal"
                    Margin="80,0,0,0" />
      </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
      <DataTemplate>
        <TextBlock HorizontalAlignment="Center"
                   Foreground="Blue"
                   Width="80"
                   Margin="5">
                        <Run Text="Room" />
                        <Run Text="{Binding Mode=OneWay}" />
        </TextBlock>
      </DataTemplate>
    </ItemsControl.ItemTemplate>
  </ItemsControl>
  <ItemsControl ItemsSource="{Binding Item1}"
                AlternationCount="{Binding Count}"
                Grid.Row="1">
    <ItemsControl.ItemTemplate>
      <DataTemplate>
        <StackPanel Orientation="Horizontal">
          <TextBlock VerticalAlignment="Center"
                     Foreground="Blue"
                     Width="80">
                        <Run Text="Unit" />
                        <Run Text="{Binding Key, Mode=OneWay}" />
          </TextBlock>
          <ItemsControl ItemsSource="{Binding Value}"
                        VerticalAlignment="Center">
            <ItemsControl.ItemsPanel>
              <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal" />
              </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
              <DataTemplate>
                <TextBlock Text="{Binding Path=Value.Cost, StringFormat={}{0:C}}"
                           Margin="5"
                           Width="80" />
              </DataTemplate>
            </ItemsControl.ItemTemplate>
          </ItemsControl>
        </StackPanel>
      </DataTemplate>
    </ItemsControl.ItemTemplate>
  </ItemsControl>
</Grid>

接着你会得到这个:

alt text


太棒了!太厉害了!你有没有想过一种使用DataGridColumnHeader和DataGridRowHeader作为表头的方法? 我认为我在寻找一个自定义控件,继承自Selector或MultiSelector,应该具有ColumnItemsSource、RowItemsSource和GeneratingCell事件,其EventArgs提供当前单元格项+单位,以及一个属性我必须提供生成单元格的DataContext,然后,它根据CellDataTemplate属性生成单元格。但由于我没有开发自定义控件的严格经验,所以很难从头开始。 - Shimmy Weitzhandler
特别是当单元格数据项未知且由用户按需提供时。同时我将使用您的解决方案,希望您能抽出时间发布自定义控件。整个社区都会因此感激您。这样的控件非常重要。 - Shimmy Weitzhandler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接