首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# WinForm DataView 與 DataTable 進階繫結技巧:去重、聯動、關聯彙總

     編輯:關於C#

DataView 提供排序、篩選、編輯狀態追蹤,配合 DataTable 關聯關係 (DataRelation) 可實現主從聯動、去重下拉選單、跨表彙總等進階 UI 互動,且完全在記憶體中運作,無需重查資料庫。本文透過完整 WinForm 範例示範三大實用技巧。

範例場景

  • 資料表:`ID` (人員)、`板塊` (技術領域)、`積分`
  • UI:comboBox1 選人員、comboBox2 顯示該人員板塊、dataGridView1 全部資料、dataGridView2 篩選後資料、dataGridView3 人員彙總 (總積分、板塊數)

核心代碼

using System;
using System.Data;
using System.Windows.Forms;

public partial class Form1 : Form
{
    private readonly DataTable _dt = new("Table1");
    private readonly DataSet _ds = new();

    public Form1()
    {
        InitializeComponent();
        InitData();
        SetupBinding();
    }

    private void InitData()
    {
        _dt.Columns.Add("ID", typeof(string));
        _dt.Columns.Add("板塊", typeof(string));
        _dt.Columns.Add("積分", typeof(int));
        _ds.Tables.Add(_dt);

        Add("jinjazz", "delphi", 50000);
        Add("jinjazz", "Sqlserver", 10000);
        Add("jinjazz", ".net", 20000);
        Add("zjcxc", "Sqlserver", 900000);
        Add("zjcxc", "vb", 10000);
        Add("zswang", "delphi", 70000);
        Add("zswang", ".net", 30000);
    }

    private void Add(string id, string catalog, int score)
    {
        var r = _dt.NewRow();
        r["ID"] = id; r["板塊"] = catalog; r["積分"] = score;
        _dt.Rows.Add(r);
    }

    private void SetupBinding()
    {
        // 1. ComboBox1:去重 ID 列表
        comboBox1.DataSource = _dt.DefaultView.ToTable(true, "ID"); // distinct
        comboBox1.DisplayMember = "ID";

        // 2. ComboBox2:板塊 (將透過 RowFilter 聯動)
        comboBox2.DataSource = new DataView(_dt);
        comboBox2.DisplayMember = "板塊";

        // 3. GridView1:全部資料
        dataGridView1.DataSource = _dt;

        // 4. GridView2:篩選檢視 (同步 ComboBox1)
        dataGridView2.DataSource = new DataView(_dt);

        // 5. 聯動:ComboBox1 選擇變更 -> 篩選 GridView2 & ComboBox2
        comboBox1.SelectedIndexChanged += (s, e) =>
        {
            string id = comboBox1.Text;
            string filter = $"ID = '{id}'";

            ((DataView)comboBox2.DataSource).RowFilter = filter;
            ((DataView)dataGridView2.DataSource).RowFilter = filter;
        };

        // 6. 彙總表:利用 DataRelation + Expression 計算欄位
        DataTable summary = _dt.DefaultView.ToTable(true, "ID"); // distinct ID
        summary.TableName = "Summary";
        _ds.Tables.Add(summary);

        var rel = new DataRelation("Rel", summary.Columns["ID"], _dt.Columns["ID"]);
        _ds.Relations.Add(rel);

        summary.Columns.Add("總積分", typeof(int), "Sum(Child(Rel).積分)");
        summary.Columns.Add("板塊數", typeof(int), "Count(Child(Rel).板塊)");

        dataGridView3.DataSource = summary;
    }
}

關鍵技巧解析

技巧核心 API說明
去重下拉選單DataView.ToTable(true, columns...)第一參數 `true` 開啟 Distinct,回傳新 DataTable 可直接繫結
多控制項同步篩選DataView.RowFilter共用同一 DataView 實例或各自建立 View,設定相同 Filter 即時生效
主從關聯彙總DataRelation + DataColumn.Expression`Sum(Child(Rel).Column)`、`Count(Child(Rel).Column)` 自動計算,無需手寫迴圈
Expression 語法DataColumn.Expression支援 `Sum`、`Count`、`Avg`、`Min`、`Max`、`Parent(Rel).Col` 等聚合與導航

進階應用

  • 巢狀主從:多層 DataRelation,Expression 可鏈式 `Child(Rel1).Child(Rel2).Col`。
  • 雙向同步:BindingSource 共用同一 DataView,編輯立即反映所有繫結控制項。
  • 效能:`RowFilter` 為字串解析,大量資料 ( > 1 萬列) 建議改用 DataView.FindRows 或預先索引。

結語

DataView + DataRelation + Expression 是 ADO.NET 記憶體資料操作的「三板斧」,善用可大幅減少資料庫往返、簡化 UI 同步邏輯、實現豐富的主從彙總介面。現代專案若使用 Entity Framework,可考慮將邏輯下推至 LINQ to Entities 或資料庫 View,但離線場景 (報表、匯入預覽、行動裝置快取) 此組合依然極具價值。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved