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ù)庫(kù)。
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ù)庫(kù)連接的值填充示例中的connectionString變量。Windows身份驗(yàn)證,也稱為集成安全,是一種比在連接字符串中存儲(chǔ)密碼更安全的連接數(shù)據(jù)庫(kù)的方式。
下列完整的代碼演示了從數(shù)據(jù)庫(kù)中檢索數(shù)據(jù),并填充到Windows窗體中的DataGridView控件。Form還有一些button用于重新加載數(shù)據(jù)和向數(shù)據(jù)庫(kù)提交更改。
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ù)庫(kù)的三種方法
在數(shù)據(jù)庫(kù)管理和維護(hù)過程中,數(shù)據(jù)的安全性和完整性至關(guān)重要,備份文件(.bak 文件)是 SQL Server 中常用的數(shù)據(jù)庫(kù)備份格式,本文將介紹從 .bak 文件恢復(fù) SQL 數(shù)據(jù)庫(kù)的基本步驟和最佳實(shí)踐,需要的朋友可以參考下2024-09-09Clickhouse系列之整合Hive數(shù)據(jù)倉(cāng)庫(kù)示例詳解
這篇文章主要為大家介紹了Clickhouse系列之整合Hive數(shù)據(jù)倉(cāng)庫(kù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10解決mac上Navicat新建數(shù)據(jù)庫(kù)3680錯(cuò)誤問題
這篇文章主要介紹了mac上Navicat新建數(shù)據(jù)庫(kù)3680錯(cuò)誤解決辦法,很多朋友遇到這個(gè)問題不知道該如何解決,網(wǎng)上一搜一大把,但是不能解決核心問題,下面小編把我的解決過程分享給大家,需要的朋友可以參考下2021-11-11數(shù)據(jù)庫(kù)查詢性能需注意幾點(diǎn)經(jīng)驗(yàn)
這篇文章主要介紹在程序編程中,需要注意數(shù)據(jù)庫(kù)的性能問題,否則會(huì)導(dǎo)致數(shù)據(jù)庫(kù)與頁(yè)面打開都很慢2013-05-05Access轉(zhuǎn)成SQL數(shù)據(jù)庫(kù)的方法
很多朋友想用SQL2000數(shù)據(jù)庫(kù)的編程方法,但是卻又苦于自己是學(xué)ACCESS的,對(duì)SQL只是一點(diǎn)點(diǎn)的了解而已,這里我給大家提供以下參考---將ACCESS轉(zhuǎn)化成SQL2000的方法和注意事項(xiàng)。2015-09-09SQL中NTEXT字段內(nèi)容顯示<long text>的原因
SQL中NTEXT字段內(nèi)容顯示<long text>的原因...2007-03-03