Compartilhar via


Visão geral da tabela

Table é um elemento de nível de bloco que dá suporte à apresentação baseada em grade do conteúdo do documento Flow. A flexibilidade desse elemento torna-o muito útil, mas também torna mais complicado entender e usar corretamente.

Este tópico inclui as seções a seguir.

Noções básicas de tabelas

Como a tabela é diferente da grade?

Table e Grid compartilhe algumas funcionalidades comuns, mas cada uma é mais adequada para cenários diferentes. Um Table foi projetado para uso no conteúdo do fluxo (consulte Visão geral do Documento de Fluxo para obter mais informações sobre o conteúdo do fluxo). Grades são mais utilizadas dentro de formulários (basicamente em qualquer lugar fora do fluxo de conteúdo). Em um FlowDocument, Table dá suporte a comportamentos de conteúdo de fluxo, como paginação, refluxo de coluna e seleção de conteúdo, enquanto um Grid não. Um Grid, por outro lado, é melhor usado fora de um FlowDocument por muitos motivos, incluindo o fato de que Grid adiciona elementos com base em um índice de linha e coluna, enquanto Table não. O elemento Grid permite camadas de conteúdo filho, permitindo que mais de um elemento exista dentro de uma única "célula". Table não suporta camadas. Elementos filhos de um Grid podem ser absolutamente posicionados em relação à área de seus limites de "célula". Table não dá suporte a esse recurso. Por fim, um Grid requer menos recursos do que um Table , portanto, considere usar um Grid para melhorar o desempenho.

Estrutura básica da tabela

Table fornece uma apresentação baseada em grade que consiste em colunas (representadas por TableColumn elementos) e linhas (representadas por TableRow elementos). TableColumn os elementos não hospedam conteúdo; eles simplesmente definem colunas e características de colunas. TableRow os elementos devem ser hospedados em um TableRowGroup elemento, que define um agrupamento de linhas para a tabela. TableCell os elementos, que contêm o conteúdo real a ser apresentado pela tabela, devem ser hospedados em um TableRow elemento. TableCell pode conter apenas elementos que derivam de Block. Elementos filho válidos para uma TableCell inclusão.

Observação

Os elementos TableCell podem não conter diretamente o texto. Para obter mais informações sobre as regras de contenção para elementos de conteúdo de fluxo, consulte TableCellVisão geral do Documento de Fluxo.

Observação

Table é semelhante ao Grid elemento, mas tem mais funcionalidades e, portanto, requer maior sobrecarga de recursos.

O exemplo a seguir define uma tabela simples 2 x 3 com XAML.

<!-- 
  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>

A figura a seguir mostra como este exemplo é renderizado.

Captura de tela que mostra como uma tabela básica é renderizada.

Contenção de tabela

Table deriva do Block elemento e adere às regras comuns para Block elementos de nível. Um Table elemento pode ser contido por qualquer um dos seguintes elementos:

Agrupamentos de linhas

O TableRowGroup elemento fornece uma maneira de agrupar arbitrariamente linhas dentro de uma tabela; cada linha em uma tabela deve pertencer a um agrupamento de linhas. As linhas dentro de um grupo de linhas geralmente compartilham uma intenção comum e podem ser estilizadas como um grupo. Um uso comum para agrupamentos de linhas é separar linhas de finalidade especial, como um título, cabeçalho e linhas de rodapé, do conteúdo primário contido na tabela.

O exemplo a seguir usa XAML para definir uma tabela com linhas de cabeçalho e rodapé com estilo.

<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>

A figura a seguir mostra como este exemplo é renderizado.

Captura de tela: Grupos de linhas de tabela

Precedência de renderização em segundo plano

Os elementos de tabela são renderizados na ordem a seguir (ordem z do mais baixo para o mais alto). Essa ordem não pode ser alterada. Por exemplo, não há nenhuma propriedade "ordem Z" para esses elementos que você pode usar para substituir essa ordem estabelecida.

  1. Table

  2. TableColumn

  3. TableRowGroup

  4. TableRow

  5. TableCell

Considere o exemplo a seguir, que define as cores de plano de fundo para cada um desses elementos dentro de uma tabela.

<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>

A figura a seguir mostra como este exemplo é renderizado (mostrando apenas cores de plano de fundo).

Captura de tela: Table z-order

Abarcando linhas ou colunas

As células de tabela podem ser configuradas para abranger várias linhas ou colunas usando os RowSpan atributos ou ColumnSpan , respectivamente.

Considere o exemplo a seguir, no qual uma célula abrange três colunas.

<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>

A figura a seguir mostra como este exemplo é renderizado.

Captura de tela: célula que abrange todas as três colunas

Criando uma tabela com código

Os exemplos a seguir mostram como criar programaticamente um Table e preenchê-lo com conteúdo. O conteúdo da tabela é distribuído em cinco linhas (representadas por objetos TableRow contidos em um objeto RowGroups) e seis colunas (representadas por objetos TableColumn). As linhas são usadas para diferentes finalidades de apresentação, incluindo uma linha de título destinada a denominar a tabela inteira, uma linha de cabeçalho para descrever as colunas de dados na tabela e uma linha de rodapé com informações resumidas. Observe que a noção de linhas "title", "header" e "footer" não é inerente à tabela; são simplesmente linhas com características diferentes. As células de tabela contêm o conteúdo real, que pode ser composto por texto, imagens ou quase qualquer outro elemento de interface do usuário (interface do usuário).

Primeiro, um FlowDocument é criado para hospedar o Tablee um novo Table é criado e adicionado ao conteúdo do 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

Em seguida, seis objetos TableColumn são criados e adicionados à coleção Columns da tabela, com alguma formatação aplicada.

Observação

Note que a coleção Columns da tabela usa indexação padrão começando do zero.

// 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

Em seguida, uma linha de título é criada e adicionada à tabela com alguma formatação aplicada. A linha de título contém uma única célula que abrange todas as seis colunas na tabela.

// 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

Em seguida, uma linha de cabeçalho é criada e adicionada à tabela e as células na linha de cabeçalho são criadas e preenchidas com conteúdo.

// 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"))))

Em seguida, uma linha para dados é criada e adicionada à tabela, e as células nessa linha são criadas e preenchidas com conteúdo. A criação dessa linha é semelhante à criação da linha de cabeçalho, com formatação ligeiramente diferente aplicada.

// 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

Por fim, uma linha de rodapé é criada, adicionada e formatada. Assim como a linha de título, o rodapé contém uma única célula que abrange todas as seis colunas na tabela.

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

Consulte também