테이블 개요

Table은 유동 문서 콘텐츠의 그리드 기반 프레젠테이션을 지원하는 블록 수준 요소입니다. 이 요소의 유연성 덕분에 이 요소는 매우 유용하지만 이해하고 제대로 사용하기가 더 복잡합니다.

이 항목에는 다음과 같은 섹션이 포함되어 있습니다.

테이블 기본 사항

Table은 Grid와 어떻게 다를까요?

TableGrid는 일부 공통 기능을 공유하지만 각각 서로 다른 시나리오에 가장 적합합니다. Table은 유동 콘텐츠 내에서 사용하도록 디자인되어 있습니다(유동 콘텐츠에 대한 자세한 내용은 유동 문서 개요 참조). 그리드는 폼 내부에서 사용하는 것이 적합합니다(기본적으로 유동 콘텐츠 외부의 모든 위치). FlowDocument 내에서 Table은 페이지 매김, 열 재배치 및 콘텐츠 선택 같은 유동 콘텐츠 동작을 지원하지만 Grid는 지원하지 않습니다. 반면 Grid는 행 및 열 인덱스를 기준으로 요소를 추가하지만 Table은 추가하지 않는다는 것을 포함하여 여러 가지 이유로 GridFlowDocument 외부에서 사용하는 것이 가장 적합합니다. Grid 요소를 사용하면 자식 콘텐츠를 겹칠 수 있으므로 단일 “셀”에 두 개 이상의 요소가 있을 수 있습니다. Table에서는 계층화를 지원하지 않습니다. Grid의 자식 요소는 "셀" 경계의 영역을 기준으로 절대 위치에 배치할 수 있습니다. Table 이 기능을 지원 하지 않습니다. 마지막으로, GridTable에 비해 요구하는 리소스가 적으므로 Grid를 사용하여 성능을 개선하는 방법을 고려해보세요.

기본 테이블 구조

Table에서는 (TableColumn 요소로 표시하는) 열과 (TableRow 요소로 표시하는) 행으로 구성되는 그리드 기반 표현을 제공합니다. TableColumn 요소는 콘텐츠를 호스트하지 않고 열 및 열 특성만 정의합니다. TableRow 요소는 테이블의 행 그룹화를 정의하는 TableRowGroup 요소에서 호스트되어야 합니다. 테이블로 표시할 실제 콘텐츠를 포함하는 TableCell 요소는 TableRow 요소에서 호스트되어야 합니다. TableCellBlock에서 파생된 요소만 포함합니다. TableCell에 대한 유효한 자식 요소가 포함됩니다.

참고

TableCell 요소는 텍스트 콘텐츠를 직접 호스트하지 않습니다. TableCell 같은 유동 콘텐츠 요소의 포함 규칙에 대한 자세한 내용은 유동 문서 개요를 참조하세요.

참고

Table 비슷합니다는 Grid 요소 하지만 더 많은 기능을 큰 리소스 오버 헤드가 필요 합니다.

다음 예제에서는 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>

다음 그림은 이 예제에서 렌더링하는 방법을 보여줍니다.

기본 테이블이 렌더링되는 방법을 보여주는 스크린샷.

테이블 포함

TableBlock 요소에서 파생하며, 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 순서" 속성은 없습니다.

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

행 및 열 확장

테이블 셀은 각각 RowSpan 또는 ColumnSpan 특성을 사용하여 여러 행이나 열에 확장되도록 구성할 수 있습니다.

셀이 세 개의 열에 걸쳐 있는 다음 예제를 살펴보겠습니다.

<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을 만들어 콘텐츠로 채우는 방법을 보여줍니다. 표의 콘텐츠는 5개 행(RowGroups 개체에 포함된 TableRow 개체로 제공됨)과 6개 열(TableColumn 개체로 제공됨)7에 할당됩니다. 행은 전체 테이블의 제목을 지정하는 제목 행, 테이블의 데이터 열을 설명하는 헤더 행 및 요약 정보가 포함된 바닥글 행 등의 여러 다른 프레젠테이션 용도로 사용됩니다. “제목”, “헤더” 및 “바닥글” 행의 개념은 테이블에 고유한 것이 아니며, 여러 다른 특성이 있는 행일 뿐입니다. 테이블 셀에는 텍스트, 이미지 또는 거의 모든 기타 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

다음으로 6개의 TableColumn 개체가 만들어지고 표의 Columns 컬렉션에 추가되며, 일부 서식 지정이 적용됩니다.

참고

표의 Columns 컬렉션은 표준 0부터 시작하는 인덱싱을 사용합니다.

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

다음으로 제목 행을 만들어 서식이 적용된 테이블에 추가합니다. 제목 행은 테이블의 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.
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

마지막으로 바닥글 행을 만들어 추가하고 서식을 지정합니다. 제목 행과 마찬가지로 바닥글에는 테이블의 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;
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

참고 항목