C#快速入門教程(29)—— ADO.NET離線元件與資料繫結

曹化宇發表於2018-11-15

本課將討論ADO.NET中幾個常用的離線元件(如DataSet、DataTable等),以及如何在Windows窗體應用中的列表和DataGridView控制元件中繫結資料。首先,需要建立一個Windows窗體應用專案,開啟Visual Studio Community 2017,通過選單項“檔案”>>“新建”>>“專案”,選擇專案型別,如下圖所示。

enter image description here

接下來,還需要通過選單項“檢視”>>“工具箱”開啟工具箱欄,如下圖所示。

enter image description here

在窗體中新增控制元件時,可以在工具箱欄中雙擊或拖拽到窗體,然後移動到指定的位置,下圖中的窗體,共新增了一個按鈕(Button)和一個文字框(TextBox)控制元件。

enter image description here

雙擊控制元件就可以開啟預設的事件響應程式碼方法,如雙擊button1按鈕,就可以看到如下程式碼段。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // button1控制元件的單擊事件響應程式碼
        }
    }
}

還記得上一課中是如何連線資料庫的嗎?這裡,我們在窗體中新增一個欄位用於儲存資料庫連線字串,並在窗體建構函式中初始化它,如下面的程式碼。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;

namespace WindowsFormsTest
{
    public partial class Form1 : Form
    {
        // 資料庫連線字串
        private string CnnStr;
        // 建構函式
        public Form1()
        {
            InitializeComponent();
            //
            // 初始化連線字串
            SqlConnectionStringBuilder sb =
                new SqlConnectionStringBuilder();
            sb.DataSource = @".\MSSQLSERVER1";
            sb.InitialCatalog = @"Cdb_Test";
            sb.IntegratedSecurity = true;
            sb.AsynchronousProcessing = true;
            sb.Pooling = true;
            CnnStr = sb.ConnectionString;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // 在這裡新增測試程式碼
        }
    }
}

程式碼中,使用私有欄位CnnStr儲存資料庫連線字串,並在建構函式中對其進行賦值;另外,不要忘了引用System.Data.SqlClient名稱空間。這裡,只使用一個窗體進行測試,所以資料庫連線字串就定義在了窗體中,實際的專案開發中,資料庫等資源可以建立一個公共的類進行有效的組織、管理和分配。

下面的程式碼會測試資料庫的連線,並將結果顯示在textBox1控制元件中。

    private void button1_Click(object sender, EventArgs e)
    {
        try
        {
            using (SqlConnection cnn = new SqlConnection(CnnStr))
            {
                cnn.Open();
                textBox1.Text = "資料庫連線成功";
            }
        }
        catch(Exception ex)
        {
            textBox1.Text = ex.Message;
        }
    }

這裡,我將測試程式碼放在了button1按鈕的單擊事件中,按F5執行程式並單擊button1按鈕,如果資料庫連線成功就會顯示如下圖所示的結果。

enter image description here

接下來主要討論離線元件的使用,如DataSet、DataTable等,並討論如何將離線元件的資料繫結到列表類控制元件和DataGridView控制元件中。下面,在Form1窗體中新增一個ListBox控制元件和一個DataGridView控制元件,如下圖所示。

enter image description here

下面的程式碼,我們將UserMain表的內容顯示到dataGridView1控制元件中。

    private void button1_Click(object sender, EventArgs e)
    {
        using (SqlConnection cnn = new SqlConnection(CnnStr))
        {
            cnn.Open();
            SqlCommand cmd = cnn.CreateCommand();
            cmd.CommandText = "select * from UserMain;";
            using (SqlDataAdapter ada = new SqlDataAdapter(cmd))
            {
                DataSet ds = new DataSet();
                ada.Fill(ds,"UserMain");
                // 資料繫結
                dataGridView1.DataSource = ds;
                dataGridView1.DataMember = "UserMain";
            }
        }
    }

本例及接下來的測試會省略異常捕捉程式碼,如果不能正確執行,可以根據丟擲的異常資訊進行除錯。程式碼執行結果如下圖所示。

enter image description here

本例中,我們使用SqlDataAdapter類的Fill()方法將查詢的資料填充到DataSet物件中,此時,會在DataSet物件中生成一個表(DataTable型別),Fill()方法的第二個引數指定了表的名稱。將DataSet中的資料繫結到DataGridView控制元件時,指定了DataGridView控制元件的兩個屬性,包括:

  • DataSource屬性,指定資料來源物件。
  • DataMember屬性,指定資料來源中的具體成員名稱。

DataSet中的Tables屬性包含了所有表的集合,可以使用表名或數值索引進行訪問,如示例中的"UserMain"表,可以使用ds.Tables[0]或ds.Tables["UserMain"]進行訪問;此外,指定DataGridView控制元件的資料來源時,還可以直接使用表物件,此時就不需要指定DataMember屬性了,如下面的程式碼。

dataGridView1.DataSource = ds.Tables["UserMain"];

將資料繫結到ListBox控制元件時,可以直接顯示一項資料,也可以顯示“鍵/值”對應的兩個資料,如下面的程式碼,將UserName作為顯示的文字,而UserID資料作為列表項的值。

    private void button1_Click(object sender, EventArgs e)
    {
        using (SqlConnection cnn = new SqlConnection(CnnStr))
        {
            cnn.Open();
            SqlCommand cmd = cnn.CreateCommand();
            cmd.CommandText = "select * from UserMain;";
            using (SqlDataAdapter ada = new SqlDataAdapter(cmd))
            {
                DataSet ds = new DataSet();
                ada.Fill(ds,"UserMain");
                // 資料繫結
                listBox1.DataSource = ds.Tables["UserMain"];
                listBox1.DisplayMember = "UserName";
                listBox1.ValueMember = "UserID";
            }
        }
    }

程式碼執行結果如下圖所示。

enter image description here

下面,我們再新增一個Button控制元件,使用預設的button2作為名稱,如下圖所示。

enter image description here

雙擊開啟button2控制元件的單擊事件響應程式碼,並新增如下內容。

    private void button2_Click(object sender, EventArgs e)
    {
        if (listBox1.SelectedIndex == -1)
        {
            textBox1.Text = "沒有選擇列表項";
        }
        else
        {
            textBox1.Text = string.Format("{0} : {1}",
                listBox1.SelectedValue, listBox1.Text);
        }
    }

執行程式,先單擊button1繫結列表資料,然後就可以通過單擊button2按鈕顯示選擇專案的數值和文字了,如下圖所示。

enter image description here

下面的程式碼會通過讀取DataTable物件中的資料,將UserName欄位的資料顯示在listBox1控制元件中。

    private void button1_Click(object sender, EventArgs e)
    {
        using (SqlConnection cnn = new SqlConnection(CnnStr))
        {
            cnn.Open();
            SqlCommand cmd = cnn.CreateCommand();
            cmd.CommandText = "select * from UserMain;";
            using (SqlDataAdapter ada = new SqlDataAdapter(cmd))
            {
                DataSet ds = new DataSet();
                ada.Fill(ds,"UserMain");
                // 讀取DataTable資料
                DataTable tbl = ds.Tables[0];
                for(int row=0;row<tbl.Rows.Count;row++)
                {
                    listBox1.Items.Add(tbl.Rows[row]["UserName"]);
                }
            }
        }
    }

DataTable物件中,Rows屬性表示所有行(資料記錄)的集合,而Columns屬性表示所有列(欄位資訊)的集合,如下面的程式碼,將在listBox1列表中顯示所有的欄位名。

    private void button1_Click(object sender, EventArgs e)
    {
        using (SqlConnection cnn = new SqlConnection(CnnStr))
        {
            cnn.Open();
            SqlCommand cmd = cnn.CreateCommand();
            cmd.CommandText = "select * from UserMain;";
            using (SqlDataAdapter ada = new SqlDataAdapter(cmd))
            {
                DataSet ds = new DataSet();
                ada.Fill(ds,"UserMain");
                // 讀取DataTable資料
                DataTable tbl = ds.Tables[0];
                for(int col=0;col<tbl.Columns.Count;col++)
                {
                    listBox1.Items.Add(tbl.Columns[col].ColumnName);
                }
            }
        }
    }

程式碼執行結果如下圖所示。

enter image description here

無論是Windows窗體應用、或者是Web窗體應用,合理地使用資料繫結功能,可以提高應用的開發效率;如果有需要,還可以建立自己的資料處理元件,大家可以在學習和工作不斷探索和嘗試。

CHY軟體小屋原創作品!

相關文章