C# - C Sharp: Bảng (Table) trong WPF


Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên

Bảng là một phần tử cấp khối hỗ trợ trình bày nội dung tài liệu Flow dựa trên lưới. Tính linh hoạt của yếu tố này làm cho nó rất hữu ích, nhưng cũng làm cho việc hiểu và sử dụng chính xác trở nên phức tạp hơn.

Khái niệm cơ bản về bảng

Bảng khác với Lưới (Grid) như thế nào?

Bảng và Lưới chia sẻ một số chức năng chung, nhưng mỗi chức năng phù hợp nhất cho các tình huống khác nhau. Bảng được thiết kế để sử dụng trong nội dung dòng. Lưới được sử dụng tốt nhất bên trong các biểu mẫu (về cơ bản ở bất kỳ đâu bên ngoài nội dung luồng). Trong FlowDocument, Bảng hỗ trợ các hành vi nội dung luồng như phân trang, chỉnh lại cột và lựa chọn nội dung trong khi Lưới thì không. Mặt khác, Lưới được sử dụng tốt nhất bên ngoài FlowDocument vì nhiều lý do bao gồm Lưới thêm các thành phần dựa trên chỉ mục hàng và cột, Bảng không làm điều này. Phần tử Lưới cho phép phân lớp nội dung con, cho phép nhiều phần tử tồn tại trong một "ô" duy nhất. Bảng không hỗ trợ xếp lớp. Các phần tử con của Lưới có thể được định vị tuyệt đối so với diện tích ranh giới "ô" của chúng. Bảng không hỗ trợ tính năng này. Cuối cùng, Lưới yêu cầu ít tài nguyên hơn Bảng, vì vậy hãy cân nhắc sử dụng Lưới để cải thiện hiệu suất.

Cấu trúc bảng cơ bản

Bảng cung cấp một bản trình bày dựa trên lưới bao gồm các cột (được biểu thị bằng các phần tử TableColumn) và các hàng (được biểu thị bằng các phần tử TableRow). Các phần tử TableColumn không lưu trữ nội dung; chúng chỉ đơn giản là xác định các cột và các đặc tính của cột. Các phần tử TableRow phải được lưu trữ trong phần tử TableRowGroup, phần tử này xác định một nhóm các hàng cho bảng. Các phần tử TableCell, chứa nội dung thực tế được trình bày bởi bảng, phải được lưu trữ trong phần tử TableRow. TableCell chỉ có thể chứa các phần tử bắt nguồn từ Block. Các phần tử con hợp lệ cho một TableCell bao gồm.

  • BlockUIContainer
  • List
  • Paragraph
  • Section
  • Table

Ghi chú

Các phần tử TableCell có thể không lưu trữ trực tiếp nội dung văn bản.

Ghi chú

Bảng tương tự như phần tử Lưới nhưng có nhiều khả năng hơn và do đó, yêu cầu chi phí tài nguyên lớn hơn.

Ví dụ sau định nghĩa một bảng 2 x 3 đơn giản với 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>

Kết quả:

Bảng 2 x xBảng 2 x x

Bảng ngăn

Bảng bắt nguồn từ phần tử Block (Khối) và tuân thủ các quy tắc chung cho các phần tử cấp Block. Một phần tử Bảng có thể được chứa bởi bất kỳ phần tử nào sau đây:

  • FlowDocument
  • TableCell
  • ListBoxItem
  • ListViewItem
  • Section
  • Floater
  • Figure

Nhóm hàng

Phần tử TableRowGroup cung cấp một cách để nhóm các hàng tùy ý trong một bảng; mỗi hàng trong bảng phải thuộc về một nhóm hàng. Các hàng trong một nhóm hàng thường chia sẻ mục đích chung và có thể được tạo kiểu như một nhóm. Một cách sử dụng phổ biến cho các nhóm hàng là để phân tách các hàng có mục đích đặc biệt, chẳng hạn như các hàng tiêu đề, đầu trang và chân trang, khỏi nội dung chính chứa trong bảng.

Ví dụ sau đây sử dụng XAML để xác định một bảng có các hàng đầu trang và chân trang được tạo kiểu.

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

Kết quả:

Bảng ngănBảng ngăn

Ưu tiên hiển thị nền

Các phần tử bảng hiển thị theo thứ tự sau (thứ tự z từ thấp nhất đến cao nhất). Thứ tự này không thể thay đổi. Ví dụ: không có thuộc tính "Z-order" cho các thành phần này mà bạn có thể sử dụng để thay thế thứ tự đã thiết lập này.

  1. Table
  2. TableColumn
  3. TableRowGroup
  4. TableRow
  5. TableCell

Hãy xem xét ví dụ sau, ví dụ này xác định màu nền cho từng thành phần này trong một bảng.

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

Kết quả:

Bảng ưu tiên hiển thị nền

Kéo dài hàng hoặc cột

Các ô của bảng có thể được định cấu hình để mở rộng nhiều hàng hoặc cột bằng cách sử dụng các thuộc tính RowSpan hoặc ColumnSpan tương ứng.

Xem xét ví dụ sau, trong đó một ô kéo dài ba cột.

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

Kết quả:

Kéo dài hàng hoặc cột của bảngKéo dài hàng hoặc cột của bảng

Xây dựng một bảng  thông qua lập trình

Các ví dụ sau đây cho ta cách tạo Bảng thông qua lập trình và điền nội dung vào đó. Nội dung của bảng được chia thành năm hàng (được đại diện bởi các đối tượng TableRow có trong một đối tượng RowGroups) và sáu cột (được đại diện bởi các đối tượng TableColumn). Các hàng được sử dụng cho các mục đích trình bày khác nhau, bao gồm một hàng tiêu đề nhằm đặt tiêu đề cho toàn bộ bảng, một hàng tiêu đề để mô tả các cột dữ liệu trong bảng và một hàng chân trang có thông tin tóm tắt. Lưu ý rằng khái niệm về các hàng "tiêu đề - title", "đầu trang - header" và "chân trang - footer" không phải là vốn có của bảng; đây chỉ là những hàng có các đặc điểm khác nhau. Các ô của bảng chứa nội dung thực tế, có thể bao gồm văn bản, hình ảnh hoặc gần như bất kỳ phần tử giao diện người dùng (UI) nào khác.

Đầu tiên, một FlowDocument được tạo để lưu trữ Table và một Table mới được tạo và thêm vào nội dung của 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;

Tiếp theo, sáu đối tượng TableColumn được tạo và thêm vào bộ sưu tập Cột của bảng, với một số định dạng được áp dụng.

Ghi chú

Lưu ý rằng bộ sưu tập Cột của bảng sử dụng lập chỉ mục dựa trên số 0 tiêu chuẩn.

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

Tiếp theo, một hàng tiêu đề được tạo và thêm vào bảng, đồng thời các ô trong hàng tiêu đề được tạo và điền nội dung.

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

Tiếp theo, một hàng dữ liệu được tạo và thêm vào bảng, đồng thời các ô trong hàng này được tạo và điền nội dung. Tạo hàng này tương tự như tạo hàng tiêu đề, với áp dụng định dạng hơi khác một chút.

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

Cuối cùng, một hàng chân trang được tạo, thêm và định dạng. Giống như hàng tiêu đề, chân trang chứa một ô kéo dài tất cả sáu cột trong bảng.

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;
» Tiếp: Model-View-ViewModel (MVVM)
« Trước: Một số thao tác với chuỗi (string)
Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên
Copied !!!