表概述

Table 是支持基于网格的 Flow 文档内容的呈现的块级元素。 此元素的灵活性使它非常有用,但也使得正确理解和使用变得更加复杂。

本主题包含以下各节:

数据表基础知识

表与网格有何不同?

TableGrid 共享一些常见功能,但每种功能最适合不同的方案。 Table 被设计用于流内容(有关流内容的更多信息,请参阅 流文档概述)。 网格最适合用于表单内部(基本上在流式内容之外的任何位置)。 在FlowDocument中,Table支持流内容行为,例如分页、列重排和内容选择,而Grid则不支持。 Grid另一方面,最好在FlowDocument之外使用,原因有很多,包括Grid会根据行索引和列索引添加元素,而Table则不会。 Grid 元素允许对子内容进行分层,使得单个“单元格”中能够存在多个元素。而 Table 元素则不支持分层。 Grid 的子元素可以相对于其“单元格”边界的区域进行绝对定位。 Table 不支持此功能。 最后, Grid 需要的资源比 Table 使用资源少,因此请考虑使用 Grid 资源来提高性能。

基本表结构

Table 提供基于网格的演示文稿,其中包含列(由 TableColumn 元素表示)和行(由 TableRow 元素表示)。 TableColumn 元素不承载内容;它们只是定义列及其特征。 TableRow 元素必须托管在元素 TableRowGroup 中,该元素定义表的行分组。 TableCell 元素(包含表要呈现的实际内容)必须托管在 TableRow 元素中。 TableCell 只能包含派生自 Block的元素。 TableCell 的有效子元素包括。

注释

TableCell 元素不能直接托管文本内容。 有关流内容元素 TableCell的包含规则的详细信息,请参阅 流文档概述

注释

Grid元素类似于Table元素,但具有更多功能,因此需要更大的资源开销。

以下示例使用 XAML 定义一个简单的 2 x 3 表。

<!-- 
  Table is a Block element, and as such must be hosted in a container
  for Block elements.  FlowDocument provides such a container. 
-->
<FlowDocument>
  <Table>
    <!-- 
      This table has 3 columns, each described by a TableColumn 
      element nested in a Table.Columns collection element. 
    -->
    <Table.Columns>
      <TableColumn />
      <TableColumn />
      <TableColumn />
    </Table.Columns>
    <!-- 
      This table includes a single TableRowGroup which hosts 2 rows,
      each described by a TableRow element.
    -->
    <TableRowGroup>
      <!--
        Each of the 2 TableRow elements hosts 3 cells, described by
        TableCell elements.
      -->
      <TableRow>
        <TableCell>
          <!-- 
            TableCell elements may only host elements derived from Block.
            In this example, Paragaph elements serve as the ultimate content
            containers for the cells in this table.
          -->
          <Paragraph>Cell at Row 1 Column 1</Paragraph>
        </TableCell>
        <TableCell>
          <Paragraph>Cell at Row 1 Column 2</Paragraph>
        </TableCell>
        <TableCell>
          <Paragraph>Cell at Row 1 Column 3</Paragraph>
        </TableCell>
      </TableRow>
      <TableRow>
        <TableCell>
          <Paragraph>Cell at Row 2 Column 1</Paragraph>
        </TableCell>
        <TableCell>
          <Paragraph>Cell at Row 2 Column 2</Paragraph>
        </TableCell>
        <TableCell>
          <Paragraph>Cell at Row 2 Column 3</Paragraph>
        </TableCell>
      </TableRow>
    </TableRowGroup>
  </Table>
</FlowDocument>

下图显示了此示例的呈现方式。

显示基本表呈现方式的屏幕截图。

表包含

Table 派生自 Block 该元素,并遵循级别元素的 Block 常见规则。 元素 Table 可以包含在以下任一元素中:

行分组

TableRowGroup 元素提供了一种方法来任意对表中的行进行分组;表中的每一行都必须属于行分组。 行组中的行通常共享一个共同目的,并且可能被作为一个整体来样式化。 行分组的常见用途是将特殊用途行(如标题、页眉和页脚行)与表包含的主要内容分开。

以下示例使用 XAML 定义具有样式的页眉和页脚行的表。

<Table>
  <Table.Resources>
    <!-- Style for header/footer rows. -->
    <Style x:Key="headerFooterRowStyle" TargetType="{x:Type TableRowGroup}">
      <Setter Property="FontWeight" Value="DemiBold"/>
      <Setter Property="FontSize" Value="16"/>
      <Setter Property="Background" Value="LightGray"/>
    </Style>

    <!-- Style for data rows. -->
    <Style x:Key="dataRowStyle" TargetType="{x:Type TableRowGroup}">
      <Setter Property="FontSize" Value="12"/>
      <Setter Property="FontStyle" Value="Italic"/>
    </Style>
  </Table.Resources>
  
  <Table.Columns>
    <TableColumn/> <TableColumn/> <TableColumn/> <TableColumn/>
  </Table.Columns>

  <!-- This TableRowGroup hosts a header row for the table. -->
  <TableRowGroup Style="{StaticResource headerFooterRowStyle}">
    <TableRow>
      <TableCell/>
      <TableCell><Paragraph>Gizmos</Paragraph></TableCell>
      <TableCell><Paragraph>Thingamajigs</Paragraph></TableCell>
      <TableCell><Paragraph>Doohickies</Paragraph></TableCell>
    </TableRow>
  </TableRowGroup>
  
  <!-- This TableRowGroup hosts the main data rows for the table. -->
  <TableRowGroup Style="{StaticResource dataRowStyle}">
    <TableRow>
      <TableCell><Paragraph Foreground="Blue">Blue</Paragraph></TableCell>
      <TableCell><Paragraph>1</Paragraph></TableCell>
      <TableCell><Paragraph>2</Paragraph></TableCell>
      <TableCell><Paragraph>3</Paragraph> </TableCell>
    </TableRow>
    <TableRow>
      <TableCell><Paragraph Foreground="Red">Red</Paragraph></TableCell>
      <TableCell><Paragraph>1</Paragraph></TableCell>
      <TableCell><Paragraph>2</Paragraph></TableCell>
      <TableCell><Paragraph>3</Paragraph></TableCell>
    </TableRow>
    <TableRow>
      <TableCell><Paragraph Foreground="Green">Green</Paragraph></TableCell>
      <TableCell><Paragraph>1</Paragraph></TableCell>
      <TableCell><Paragraph>2</Paragraph></TableCell>
      <TableCell><Paragraph>3</Paragraph></TableCell>
    </TableRow>
  </TableRowGroup>

  <!-- This TableRowGroup hosts a footer row for the table. -->
  <TableRowGroup Style="{StaticResource headerFooterRowStyle}">
    <TableRow>
      <TableCell><Paragraph>Totals</Paragraph></TableCell>
      <TableCell><Paragraph>3</Paragraph></TableCell>
      <TableCell><Paragraph>6</Paragraph></TableCell>
      <TableCell>
        <Table></Table>
      </TableCell>
    </TableRow>
  </TableRowGroup>
</Table>

下图显示了此示例的呈现方式。

屏幕截图:表行组

背景渲染优先级

表元素按以下顺序呈现(z 顺序从最低到最高)。 无法更改此顺序。 例如,这些元素没有“Z-order”属性可以用来重写已建立的顺序。

  1. Table

  2. TableColumn

  3. TableRowGroup

  4. TableRow

  5. TableCell

请考虑以下示例,该示例定义表中每个元素的背景色。

<Table Background="Yellow">
  <Table.Columns>
    <TableColumn/>
    <TableColumn Background="LightGreen"/>
    <TableColumn/>
  </Table.Columns>
  <TableRowGroup>
    <TableRow>
      <TableCell/><TableCell/><TableCell/>
    </TableRow>
  </TableRowGroup>
  <TableRowGroup Background="Tan">
    <TableRow>
      <TableCell/><TableCell/><TableCell/>
    </TableRow>
    <TableRow Background="LightBlue">
      <TableCell/><TableCell Background="Purple"/><TableCell/>
    </TableRow>
    <TableRow>
      <TableCell/><TableCell/><TableCell/>
    </TableRow>
  </TableRowGroup>
  <TableRowGroup>
    <TableRow>
      <TableCell/><TableCell/><TableCell/>
    </TableRow>
  </TableRowGroup>
</Table>

下图显示了此示例的呈现方式(仅显示背景色)。

屏幕截图:表 z 顺序

跨越行或列

可以分别使用 RowSpanColumnSpan 属性将表单元格配置为跨多行或多列。

请考虑以下示例,其中单元格跨越三列。

<Table>
  <Table.Columns>
    <TableColumn/>
    <TableColumn/>
    <TableColumn/>
  </Table.Columns>

  <TableRowGroup>
    <TableRow>
      <TableCell ColumnSpan="3" Background="Cyan">
        <Paragraph>This cell spans all three columns.</Paragraph>
      </TableCell>
    </TableRow>
    <TableRow>
      <TableCell Background="LightGray"><Paragraph>Cell 1</Paragraph></TableCell>
      <TableCell Background="LightGray"><Paragraph>Cell 2</Paragraph></TableCell>
      <TableCell Background="LightGray"><Paragraph>Cell 3</Paragraph></TableCell>
    </TableRow>
  </TableRowGroup>
</Table>

下图显示了此示例的呈现方式。

屏幕截图:单元格跨越所有三列

使用代码构建表格

以下示例演示如何以编程方式创建 Table 并使用内容填充它。 表的内容分为五行(由 TableRow 对象中包含的 RowGroups 对象表示)和六列(由 TableColumn 对象表示)。 这些行用于不同的呈现目的,包括用于标题整个表的标题行、用于描述表中数据的列的标题行,以及包含摘要信息的页脚行。 请注意,“标题”、“页眉”和“页脚”行的概念不是表格固有的,这些只是具有不同特征的行。 表格单元格包含实际内容,这些内容可以由文本、图像或几乎任何其他用户界面 (UI) 元素组成。

首先,创建一个 FlowDocument 来托管 Table,并创建一个新的 Table 并将其添加到 FlowDocument的内容。

// Create the parent FlowDocument...
flowDoc = new FlowDocument();

// Create the Table...
table1 = new Table();
// ...and add it to the FlowDocument Blocks collection.
flowDoc.Blocks.Add(table1);

// Set some global formatting properties for the table.
table1.CellSpacing = 10;
table1.Background = Brushes.White;
' Create the parent FlowDocument...
flowDoc = New FlowDocument()

' Create the Table...
table1 = New Table()

' ...and add it to the FlowDocument Blocks collection.
flowDoc.Blocks.Add(table1)


' Set some global formatting properties for the table.
table1.CellSpacing = 10
table1.Background = Brushes.White

接下来,将创建六个 TableColumn 对象并将其添加到表的 Columns 集合中,并应用了一些格式。

注释

请注意,表的 Columns 集合使用标准从零开始的索引。

// Create 6 columns and add them to the table's Columns collection.
int numberOfColumns = 6;
for (int x = 0; x < numberOfColumns; x++)
{
    table1.Columns.Add(new TableColumn());

    // Set alternating background colors for the middle colums.
    if(x%2 == 0)
        table1.Columns[x].Background = Brushes.Beige;
    else
        table1.Columns[x].Background = Brushes.LightSteelBlue;
}

' Create 6 columns and add them to the table's Columns collection.
Dim numberOfColumns = 6
Dim x
For x = 0 To numberOfColumns
    table1.Columns.Add(new TableColumn())

    ' Set alternating background colors for the middle colums.
    If x Mod 2 = 0 Then
        table1.Columns(x).Background = Brushes.Beige
    Else
        table1.Columns(x).Background = Brushes.LightSteelBlue
    End If
Next x

接下来,将创建标题行并将其添加到已应用某些格式的表格中。 标题行恰好包含一个跨表中所有六列的单元格。

// Create and add an empty TableRowGroup to hold the table's Rows.
table1.RowGroups.Add(new TableRowGroup());

// Add the first (title) row.
table1.RowGroups[0].Rows.Add(new TableRow());

// Alias the current working row for easy reference.
TableRow currentRow = table1.RowGroups[0].Rows[0];

// Global formatting for the title row.
currentRow.Background = Brushes.Silver;
currentRow.FontSize = 40;
currentRow.FontWeight = System.Windows.FontWeights.Bold;

// Add the header row with content,
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("2004 Sales Project"))));
// and set the row to span all 6 columns.
currentRow.Cells[0].ColumnSpan = 6;
' Create and add an empty TableRowGroup to hold the table's Rows.
table1.RowGroups.Add(new TableRowGroup())

' Add the first (title) row.
table1.RowGroups(0).Rows.Add(new TableRow())

' Alias the current working row for easy reference.
Dim currentRow As New TableRow()
currentRow = table1.RowGroups(0).Rows(0)

' Global formatting for the title row.
currentRow.Background = Brushes.Silver
currentRow.FontSize = 40
currentRow.FontWeight = System.Windows.FontWeights.Bold

' Add the header row with content, 
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("2004 Sales Project"))))
' and set the row to span all 6 columns.
currentRow.Cells(0).ColumnSpan = 6

接下来,将创建标题行并将其添加到表中,并创建标题行中的单元格并填充内容。

// Add the second (header) row.
table1.RowGroups[0].Rows.Add(new TableRow());
currentRow = table1.RowGroups[0].Rows[1];

// Global formatting for the header row.
currentRow.FontSize = 18;
currentRow.FontWeight = FontWeights.Bold;

// Add cells with content to the second row.
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Product"))));
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Quarter 1"))));
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Quarter 2"))));
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Quarter 3"))));
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Quarter 4"))));
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("TOTAL"))));
' Add the second (header) row.
table1.RowGroups(0).Rows.Add(new TableRow())
currentRow = table1.RowGroups(0).Rows(1)

' Global formatting for the header row.
currentRow.FontSize = 18
currentRow.FontWeight = FontWeights.Bold

' Add cells with content to the second row.
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Product"))))
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Quarter 1"))))
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Quarter 2"))))
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Quarter 3"))))
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Quarter 4"))))
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("TOTAL"))))

接下来,将创建数据行并将其添加到表中,并创建此行中的单元格并填充内容。 生成此行类似于生成标题行,应用的格式略有不同。

// Add the third row.
table1.RowGroups[0].Rows.Add(new TableRow());
currentRow = table1.RowGroups[0].Rows[2];

// Global formatting for the row.
currentRow.FontSize = 12;
currentRow.FontWeight = FontWeights.Normal;

// Add cells with content to the third row.
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Widgets"))));
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("$50,000"))));
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("$55,000"))));
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("$60,000"))));
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("$65,000"))));
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("$230,000"))));

// Bold the first cell.
currentRow.Cells[0].FontWeight = FontWeights.Bold;
' Add the third row.
table1.RowGroups(0).Rows.Add(new TableRow())
currentRow = table1.RowGroups(0).Rows(2)

' Global formatting for the row.
currentRow.FontSize = 12
currentRow.FontWeight = FontWeights.Normal

' Add cells with content to the third row.
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Widgets"))))
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("$50,000"))))
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("$55,000"))))
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("$60,000"))))
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("$65,000"))))
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("$230,000"))))

' Bold the first cell.
currentRow.Cells(0).FontWeight = FontWeights.Bold

最后,创建、添加脚注行并设置其格式。 与标题行一样,页脚包含一个跨表格中所有六列的单元格。

table1.RowGroups[0].Rows.Add(new TableRow());
currentRow = table1.RowGroups[0].Rows[3];

// Global formatting for the footer row.
currentRow.Background = Brushes.LightGray;
currentRow.FontSize = 18;
currentRow.FontWeight = System.Windows.FontWeights.Normal;

// Add the header row with content,
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Projected 2004 Revenue: $810,000"))));
// and set the row to span all 6 columns.
currentRow.Cells[0].ColumnSpan = 6;
table1.RowGroups(0).Rows.Add(new TableRow())
currentRow = table1.RowGroups(0).Rows(3)

' Global formatting for the footer row.
currentRow.Background = Brushes.LightGray
currentRow.FontSize = 18
currentRow.FontWeight = System.Windows.FontWeights.Normal

' Add the header row with content, 
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Projected 2004 Revenue: $810,000"))))
' and set the row to span all 6 columns.
currentRow.Cells(0).ColumnSpan = 6

另请参阅