C#表格開發(fā)之DataGridView控件詳解
一、概要
使用DataGridView控件,您可以顯示和編輯來自許多不同類型數(shù)據(jù)源的表格數(shù)據(jù)。
DataGridView控件為顯示數(shù)據(jù)提供了一個(gè)可定制的表格。DataGridView類允許通過使用DefaultCellStyle、ColumnHeadersDefaultCellStyle、CellBorderStyle和GridColor等屬性來定制單元格、行、列和邊框。
無論有或沒有底層數(shù)據(jù)源的數(shù)據(jù),你都可以在使用DataGridView控件顯示出你所期望顯示的數(shù)據(jù)。
如果沒有指定的數(shù)據(jù)源,你可以創(chuàng)建包含數(shù)據(jù)的rows和coumns,并使用DataGridView類里的Rows和Columns屬性將它們直接添加到DataGridView控件中。您可以使用Rows集合來訪問DataGridViewRow對(duì)象,也可以使用DataGridViewRow.Cell屬性直接讀取或?qū)懭雴卧裰?。另外,還有 Item[] 索引器提供了對(duì)單元格的直接訪問。
您可以設(shè)置DataSource和DataMember屬性,以將DataGridView控件綁定到數(shù)據(jù)源并自動(dòng)向其填充數(shù)據(jù),這種方法可以做為手動(dòng)填充數(shù)據(jù)的替代方法。但是前提條件是必須有指定的數(shù)據(jù)源。
當(dāng)處理大量數(shù)據(jù)時(shí),可以將VirtualMode屬性設(shè)置為true,以顯示可用數(shù)據(jù)的子集。虛擬模式需要實(shí)現(xiàn)數(shù)據(jù)緩存,從中填充DataGridView控件。
二、手動(dòng)填充數(shù)據(jù)
1、如何手動(dòng)填充數(shù)據(jù)
下面的代碼示例演示如何創(chuàng)建一個(gè)未綁定的DataGridView;設(shè)置ColumnHeadersVisible、 ColumnHeadersDefaultCellStyle和ColumnCount屬性;并使用Rows屬性和Columns屬性。
它還演示了如何使用AutoResizeColumnHeadersHeight()和AutoResizeRows()方法的一個(gè)版本,來適當(dāng)?shù)卣{(diào)整列標(biāo)頭和行的大小。
要運(yùn)行此示例,請(qǐng)將以下代碼粘貼到包含名為dataGridView1的DataGridView和名為Button1的button的表格中,然后從表格的構(gòu)造函數(shù)或Load事件處理程序調(diào)用InitializeDataGridView()方法。確保所有事件都與其事件處理程序相連接。
public Form1()
{
InitializeComponent();
InitializeDataGridView();
}
private void InitializeDataGridView()
{
// Create an unbound DataGridView by declaring a column count.
dataGridView1.ColumnCount = 4;
dataGridView1.ColumnHeadersVisible = true;
// Set the column header style.
DataGridViewCellStyle columnHeaderStyle = new DataGridViewCellStyle();
columnHeaderStyle.BackColor = Color.Beige;
columnHeaderStyle.Font = new Font("Verdana", 10, FontStyle.Bold);
dataGridView1.ColumnHeadersDefaultCellStyle = columnHeaderStyle;
// Set the column header names.
dataGridView1.Columns[0].Name = "Recipe";
dataGridView1.Columns[1].Name = "Category";
dataGridView1.Columns[2].Name = "Main Ingredients";
dataGridView1.Columns[3].Name = "Rating";
// Populate the rows.
string[] row1 = new string[] { "Meatloaf", "Main Dish", "ground beef", "**" };
string[] row2 = new string[] { "Key Lime Pie", "Dessert", "lime juice, evaporated milk", "****" };
string[] row3 = new string[] { "Orange-Salsa Pork Chops", "Main Dish", "pork chops, salsa, orange juice", "****" };
string[] row4 = new string[] { "Black Bean and Rice Salad", "Salad", "black beans, brown rice", "****" };
string[] row5 = new string[] { "Chocolate Cheesecake", "Dessert", "cream cheese", "***" };
string[] row6 = new string[] { "Black Bean Dip", "Appetizer", "black beans, sour cream", "***" };
object[] rows = new object[] { row1, row2, row3, row4, row5, row6 };
foreach (string[] rowArray in rows)
{
dataGridView1.Rows.Add(rowArray);
}
}
private void button1_Click(object sender, System.EventArgs e)
{
// Resize the height of the column headers.
dataGridView1.AutoResizeColumnHeadersHeight();
// Resize all the row heights to fit the contents of all non-header cells.
dataGridView1.AutoResizeRows( DataGridViewAutoSizeRowsMode.AllCellsExceptHeaders);
}
private void InitializeContextMenu()
{
// Create the menu item.
ToolStripMenuItem getRecipe = new ToolStripMenuItem("Search for recipe", null,
new System.EventHandler(ShortcutMenuClick));
// Add the menu item to the shortcut menu.
ContextMenuStrip recipeMenu = new ContextMenuStrip();
recipeMenu.Items.Add(getRecipe);
// Set the shortcut menu for the first column.
dataGridView1.Columns[0].ContextMenuStrip = recipeMenu;
dataGridView1.MouseDown += new MouseEventHandler(dataGridView1_MouseDown);
}
private DataGridViewCell clickedCell;
//當(dāng)鼠標(biāo)指針位于控件上并按下鼠標(biāo)鍵時(shí)發(fā)生。
private void dataGridView1_MouseDown(object sender, MouseEventArgs e)
{
// If the user right-clicks a cell, store it for use by the shortcut menu.
if (e.Button == MouseButtons.Right)
{
DataGridView.HitTestInfo hit = dataGridView1.HitTest(e.X, e.Y);
if (hit.Type == DataGridViewHitTestType.Cell)
{
clickedCell =
dataGridView1.Rows[hit.RowIndex].Cells[hit.ColumnIndex];
}
}
}
private void ShortcutMenuClick(object sender, System.EventArgs e)
{
if (clickedCell != null)
{
//Retrieve the recipe name.
string recipeName = (string)clickedCell.Value;
//Search for the recipe.
System.Diagnostics.Process.Start(
"http://search.msn.com/results.aspx?q=" + recipeName);
//null);
}
}上述代碼中,先創(chuàng)建數(shù)個(gè)字符串?dāng)?shù)組,數(shù)組的元素?cái)?shù)量等于dataGridView1的列的數(shù)量。然后在循環(huán)中,調(diào)用dataGridView1.Rows.Add(rowArray);方法,將數(shù)組元素填充進(jìn)dataGridView1的某行中。
2、如何插入一行數(shù)據(jù)
如果你想要向DataGridView表格中插入一行數(shù)據(jù),可以使用下面代碼:
this.dataGridView1.Rows.Insert(0, "one", "two", "three", "four");
該行代碼表示向dataGridView1中插入一條數(shù)據(jù)到第0行。
如果你想要插入一行空的單元格,可以使用下列代碼:
this.dataGridView1.Rows.Insert(0, "", "", "", "");
Rows屬性,不但包括值,還包括樣式信息。因此,你可以根據(jù)已設(shè)置樣式的現(xiàn)有行添加或插入行,這時(shí),你可以使用AddCopy()、AddCopies()、InsertCopy()和InsertCopies()方法來做到這一點(diǎn)。
你還可以使用Rows集合修改控件中的值或刪除行。無論控件是否綁定到外部數(shù)據(jù)源,都可以修改值或刪除行。如果存在數(shù)據(jù)源,則直接對(duì)數(shù)據(jù)源進(jìn)行更改。但是,您可能仍然需要將數(shù)據(jù)源更新推送到遠(yuǎn)程數(shù)據(jù)庫。
3、如何修改單元格值
下面的示例向您展示如何以編程方式修改單元格值。
// Modify the value in the first cell of the second row. this.dataGridView1.Rows[1].Cells[0].Value = "new value"; // The previous line is equivalent to the following line. this.dataGridView1[0, 1].Value = "new value";
除了標(biāo)準(zhǔn)集合功能之外,您還可以使用Rows集合來檢索行信息。例如,你可以使用GetRowState()方法確定特定行的狀態(tài),也可以使用GetRowCount()和GetRowsHeight()方法來確定特定狀態(tài)下的行數(shù)或行的組合高度。
如果你要檢索具有特定狀態(tài)的行索引,可以使用GetFirstRow()、GetLastRow()、GetNextRow()和GetPreviousRow()方法。
下面的示例向您展示如何檢索第一個(gè)選定行的索引,然后使用它以編程方式刪除該行。
Int32 rowToDelete = this.dataGridView1.Rows.GetFirstRow(DataGridViewElementStates.Selected);
if (rowToDelete > -1)
{
this.dataGridView1.Rows.RemoveAt(rowToDelete);
}上述代碼,是在選定某些行的時(shí)候,刪除選中行里的第一行。注意:選中行時(shí)是包含行頭在內(nèi)。如下圖所示 :

為了提高性能,Rows屬性返回的DataGridViewRowCollection可以包括共享行和非共享行。共享行共享內(nèi)存,以減少大型記錄集的成本。如果您的記錄集非常大,那么在訪問rows屬性時(shí)應(yīng)該小心地盡可能多地保持行共享。
三、DataGridView控件綁定數(shù)據(jù)源
1、概述
DataGridView控件支持標(biāo)準(zhǔn)的Windows窗體數(shù)據(jù)綁定模型,因此它可以綁定到各種數(shù)據(jù)源。通常,您綁定到管理與數(shù)據(jù)源交互的BindingSource。BindingSource可以是任何Windows窗體數(shù)據(jù)源,這在選擇或修改數(shù)據(jù)位置時(shí)為您提供了極大的靈活性。
將數(shù)據(jù)綁定到DataGridView控件是直接和直觀的,在許多情況下,它就像設(shè)置DataSource屬性一樣簡(jiǎn)單。當(dāng)綁定到包含多個(gè)列表或表的數(shù)據(jù)源時(shí),請(qǐng)將DataMember屬性設(shè)置為指定要綁定到的列表或表的字符串。
DataGridView控件支持標(biāo)準(zhǔn)的Windows窗體數(shù)據(jù)綁定模型,因此它將綁定到以下列表中描述的類的實(shí)例:
- 實(shí)現(xiàn)IList接口的任何類,包括一維數(shù)組。
- 實(shí)現(xiàn)IListSource接口的任何類,例如DataTable和DataSet類。
- 任何實(shí)現(xiàn)IBindingList接口的類,例如BindingList<T>類。
- 任何實(shí)現(xiàn)IBindingListView接口的類,比如BindingSource類。
DataGridView控件支持將數(shù)據(jù)綁定到這些接口返回的對(duì)象的公共屬性,或者綁定到ICustomTypeDescriptor接口返回的屬性集合(如果在返回的對(duì)象上實(shí)現(xiàn)的話)。
通常,您將DataGridView綁定到一個(gè)BindingSource組件,并將BindingSource組件綁定到另一個(gè)數(shù)據(jù)源,或者用業(yè)務(wù)對(duì)象填充它。
BindingSource組件是首選的數(shù)據(jù)源,因?yàn)樗梢越壎ǖ礁鞣N各樣的數(shù)據(jù)源,并且可以自動(dòng)解決許多數(shù)據(jù)綁定問題。
2、將DataGridView綁定到BindingSource
連接DataGridView控件到data的步驟:
- 實(shí)現(xiàn)一個(gè)方法來處理檢索數(shù)據(jù)的細(xì)節(jié)。下面的代碼示例實(shí)現(xiàn)了一個(gè)GetData方法,該方法初始化一個(gè)SqlDataAdapter,并使用它來填充一個(gè)DataTable。然后將DataTable綁定到BindingSource。
- 在Form的Load事件處理程序中,將DataGridView控件綁定到BindingSource,并調(diào)用GetData方法來檢索數(shù)據(jù)。
用您的Northwind SQL Server示例數(shù)據(jù)庫連接的值填充示例中的connectionString變量。Windows身份驗(yàn)證,也稱為集成安全,是一種比在連接字符串中存儲(chǔ)密碼更安全的連接數(shù)據(jù)庫的方式。
下列完整的代碼演示了從數(shù)據(jù)庫中檢索數(shù)據(jù),并填充到Windows窗體中的DataGridView控件。Form還有一些button用于重新加載數(shù)據(jù)和向數(shù)據(jù)庫提交更改。
using System;
using System.Data;
using System.Data.SqlClient;
using System.Globalization;
using System.Windows.Forms;
namespace WindowsFormsApp
{
public class BindSourceForm1 : Form
{
private DataGridView dataGridView1 = new DataGridView();
private BindingSource bindingSource1 = new BindingSource();
private SqlDataAdapter dataAdapter = new SqlDataAdapter();
private Button reloadButton = new Button();
private Button submitButton = new Button();
// Initialize the form.
public Form1()
{
InitializeComponent();
dataGridView1.Dock = DockStyle.Fill;
reloadButton.Text = "Reload";
submitButton.Text = "Submit";
reloadButton.Click += new EventHandler(ReloadButton_Click);
submitButton.Click += new EventHandler(SubmitButton_Click);
FlowLayoutPanel panel = new FlowLayoutPanel
{
Dock = DockStyle.Top,
AutoSize = true
};
panel.Controls.AddRange(new Control[] { reloadButton, submitButton });
Controls.AddRange(new Control[] { dataGridView1, panel });
Load += new EventHandler(Form1_Load);
Text = "DataGridView data binding and updating demo";
}
private void GetData(string selectCommand)
{
try
{
// Specify a connection string.
// Replace <SQL Server> with the SQL Server for your Northwind sample database.
// Replace "Integrated Security=True" with user login information if necessary.
String connectionString =
"Data Source=(local);Initial Catalog=Northwind;" +
"Integrated Security=True";
// Create a new data adapter based on the specified query.
dataAdapter = new SqlDataAdapter(selectCommand, connectionString);
// Create a command builder to generate SQL update, insert, and
// delete commands based on selectCommand.
SqlCommandBuilder commandBuilder = new SqlCommandBuilder(dataAdapter);
// Populate a new data table and bind it to the BindingSource.
DataTable table = new DataTable
{
Locale = CultureInfo.InvariantCulture
};
dataAdapter.Fill(table);
bindingSource1.DataSource = table;
// Resize the DataGridView columns to fit the newly loaded content.
dataGridView1.AutoResizeColumns(
DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader);
}
catch (SqlException)
{
MessageBox.Show("To run this example, replace the value of the " +
"connectionString variable with a connection string that is " +
"valid for your system.");
}
}
private void Form1_Load(object sender, EventArgs e)
{
// Bind the DataGridView to the BindingSource
// and load the data from the database.
dataGridView1.DataSource = bindingSource1;
GetData("select * from Customers");
}
private void ReloadButton_Click(object sender, EventArgs e)
{
// Reload the data from the database.
GetData(dataAdapter.SelectCommand.CommandText);
}
private void SubmitButton_Click(object sender, EventArgs e)
{
// Update the database with changes.
dataAdapter.Update((DataTable)bindingSource1.DataSource);
}
}
}總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
從Bak文件中恢復(fù)SQL數(shù)據(jù)庫的三種方法
在數(shù)據(jù)庫管理和維護(hù)過程中,數(shù)據(jù)的安全性和完整性至關(guān)重要,備份文件(.bak 文件)是 SQL Server 中常用的數(shù)據(jù)庫備份格式,本文將介紹從 .bak 文件恢復(fù) SQL 數(shù)據(jù)庫的基本步驟和最佳實(shí)踐,需要的朋友可以參考下2024-09-09
Clickhouse系列之整合Hive數(shù)據(jù)倉庫示例詳解
這篇文章主要為大家介紹了Clickhouse系列之整合Hive數(shù)據(jù)倉庫示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
解決mac上Navicat新建數(shù)據(jù)庫3680錯(cuò)誤問題
這篇文章主要介紹了mac上Navicat新建數(shù)據(jù)庫3680錯(cuò)誤解決辦法,很多朋友遇到這個(gè)問題不知道該如何解決,網(wǎng)上一搜一大把,但是不能解決核心問題,下面小編把我的解決過程分享給大家,需要的朋友可以參考下2021-11-11
數(shù)據(jù)庫查詢性能需注意幾點(diǎn)經(jīng)驗(yàn)
這篇文章主要介紹在程序編程中,需要注意數(shù)據(jù)庫的性能問題,否則會(huì)導(dǎo)致數(shù)據(jù)庫與頁面打開都很慢2013-05-05
Access轉(zhuǎn)成SQL數(shù)據(jù)庫的方法
很多朋友想用SQL2000數(shù)據(jù)庫的編程方法,但是卻又苦于自己是學(xué)ACCESS的,對(duì)SQL只是一點(diǎn)點(diǎn)的了解而已,這里我給大家提供以下參考---將ACCESS轉(zhuǎn)化成SQL2000的方法和注意事項(xiàng)。2015-09-09
SQL中NTEXT字段內(nèi)容顯示<long text>的原因
SQL中NTEXT字段內(nèi)容顯示<long text>的原因...2007-03-03

