使用 DataGrid 控件






4.76/5 (56投票s)
2005 年 3 月 31 日
6分钟阅读

798131

27988
ADO.NET 控件使用介绍。
引言
这个用于 DataGrid
的小型应用程序允许用户
- 在
DataGrid
中添加新行。 - 保存或更新
DataGrid
中的一行。 - 从
DataGrid
中删除现有行。 - 从 XML 文件读取数据。
- 将
DataSet
的当前数据复制到 C:\ 根目录下的三个文件- MyXMLText.txt (文本文件)
- MyXMLdata.xml (XML 文件)
- MyXMLschema.xsd (架构文件)
- 将表的当前数据写入 C:\ 上的文本文件。
“DataGrid 应用程序”中的 DataGrid
控件绑定到单个 DataSet
对象。“DataGrid 应用程序”的 DataSet
对象最初使用 OleDbDataAdapter
对象从数据库填充。
什么是 DataGrid?
Windows 窗体 DataGrid
控件为 ADO.NET 数据集提供用户界面,以可滚动网格显示 ADO.NET 表格数据,并允许更新数据源。如果 DataGrid
绑定到包含单个表且没有关系的数据库,数据将以简单的行和列显示,就像电子表格一样。DataGrid
控件是 Windows 窗体中最有用和最灵活的控件之一。一旦 DataGrid
控件设置为有效数据源,控件就会自动填充,通过根据数据结构创建列和行。DataGrid
控件可以用于显示单个表或一组表之间的层次关系。
例如:如果您将 DataGrid
绑定到具有多个相关表的数据,并且启用了 DataGrid
上的导航,则 DataGrid
会在每一行中显示所谓的“展开器”。
通过展开器,您可以从父表导航到子表。如果您单击 DataGrid
中的节点,它会显示子表。如果您单击“后退”按钮,它会显示原始父表。以这种方式,网格显示表之间的层次关系。
请记住,DataGrid
中一次只能显示一个表。DataGrid
的有效数据源包括
DataTable
数据视图
DataSet
DataViewManager
- 一维数组
- 任何实现
IListSource
接口的组件。
如何以编程方式在 DataGrid 中显示数据?
如果您想在 DataGrid
中显示数据,您需要定义一个 DataGrid
对象。当然,有不同的方法来填充 DataGrid
中的数据。例如
首先定义一个 DataGrid
并声明一个新的 DataGrid
,然后设置 DataGrid
的一些属性(位置、名称、大小等)。
private System.Windows.Forms.DataGrid dataGrid1;
this.dataGrid1 = new System.Windows.Forms.DataGrid();
this.dataGrid1.Location = new System.Drawing.Point(16, 40);
this.dataGrid1.Name = "dataGrid1";
this.dataGrid1.Size = new System.Drawing.Size(256, 176);
现在我们可以将所有必要的命令放入一个方法 "fnDisplayDataInDataGrid()
" 中,以在 DataGrid
中显示数据。
private void fnDisplayDataInDataGrid()
{
string conStr ="Integrated Security=SSPI;" +
"Initial Catalog=Northwind;" +
"Data Source=SONY\\MYSQLSERVER;";
SqlConnection conn = new SqlConnection(conStr);
// Open the connection
conn.Open();
// Create a data adapter object
SqlDataAdapter adapter = new SqlDataAdapter("SELECT * FROM MyTable", conn);
// Create a DataSet object
DataSet ds = new DataSet();
// filling the DataSet
adapter.Fill(ds,"MyTable");
// you can use one of the followings.Both works fine.
// this.dataGrid1.SetDataBinding(ds,"MyTable"); or
this.dataGrid1.DataSource=ds.DefaultViewManager;
}
此时,我将向您推荐我的上一篇文章(面向初学者的 ADO.NET 使用指南),您可以在其中找到更多关于 DataGrid
的有趣提示和技巧(即,如何捕获 DataGrid
中的按键事件 - 上、下、Esc 等)。
工作原理
连接到 MS Access 数据库后,所有记录都将显示在 DataGrid
上。
首次运行应用程序时,将调用方法 "fnRefresh()
"。它清除 DataSet
的内容,填充 DataAdapter
,并在 DataGrid
中显示数据源中的数据。之后,所有按钮都已准备好使用。以下是方法 "fnRefresh()
" 的代码片段
private void fnRefresh()
{
this.dataSet11.Clear();
this.oleDbDataAdapter1.Fill(this.dataSet11,"MyContactsTable");
this.dataGrid1.DataSource=this.dataSet11.Tables["MyContactsTable"].DefaultView;
}
插入新行
如果您单击“插入”按钮添加新记录,则 DataGrid
上的最后一行将被选中,并且之前单击的行将被取消选中。输入该行的数据后,单击“保存/更新”按钮保存新行。这是插入新行的方法
private void fnInsertNew()
{
//keep in mind the previous clicked row to unselect
int iPrevRowindex=this.iRowIndex;
MessageBox.Show("Enter the new record at the end" +
" of the DataGrid and click 'Save/Update'-button", "Stop");
this.btInsertnew.Enabled=false;
//get how many records in the table
this.iRowIndex=this.dataSet11.Tables["MyContactsTable"].Rows.Count;
//select the last row
this.dataGrid1.Select(this.iRowIndex);
//unselect the previous row
this.dataGrid1.UnSelect(iPrevRowindex);
}
保存或更新新/更改的行
方法 "fnSaveUpdate()
" 的代码片段将 DataSet
中所做的更改保存回数据库。dataSet11
的 "GetChanges
" 方法将返回一个新的 DataSet
,名为 "myChangedDataset
",其中包含所有已修改(更新、删除或插入)的行。如果未进行任何更改,则 "GetChanges
" 方法返回一个 "null
" DataSet
。
如果在更新数据库时发生任何类型的错误,OleDbDataAdapter
的 "Update
" 方法将生成一个异常。此逻辑包含在 try
/catch
块中。如果发生异常,您将收到一个消息框,通知您错误。然后调用 "RejectChanges
" 方法以放弃您所做的更改。如果进行了任何更改,系统会告知用户受影响/更改的行数,并且 "AcceptChanges()
" 方法将把所做的更改标记为 DataSet
中的永久更改。现在我们需要使用 "fnRefresh()
" 方法调用刷新 DataSet
。我认为这是更新数据库时一种“简单”而稳健的技术。
以下是“fnSaveUpdate()
”方法的代码片段
private void fnSaveUpdate()
{
try
{
//put the modified DataSet into a new DataSet(myChangedDataset)
DataSet myChangedDataset= this.dataSet11.GetChanges();
if (myChangedDataset != null)
{
//get how many rows changed
int modifiedRows = this.oleDbDataAdapter1.Update(myChangedDataset);
MessageBox.Show("Database has been updated successfully: " +
modifiedRows + " Modified row(s) ", "Success");
this.dataSet11.AcceptChanges(); //accept the all changes
fnRefresh();
}
else
}
MessageBox.Show("Nothing to save", "No changes");
}//if-else
}
catch(Exception ex)
{
//if something somehow went wrong
MessageBox.Show("An error occurred updating the database: " +
ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
this.dataSet11.RejectChanges(); //cancel the changes
}//try-catch
fnEnableDisableAllButtons(true);
}
删除当前行
在删除行之前询问用户始终是一个好习惯。单击“是”后,DataGrid
上的当前行将被删除、更新和刷新。删除行的方法如下
private void fnDelete()
{
//ask user if wanting to delete
DialogResult dr=MessageBox.Show("Are you sure you want to delete this row ? ",
"Confirm deleting", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (dr ==DialogResult.Yes)
{
DataTable tbl=new DataTable("MyContactsTable");
tbl=this.dataSet11.Tables[0];
int i=this.iRowIndex;//get the index of the row you clicked
tbl.Rows[i].Delete(); //delete the row
this.oleDbDataAdapter1.Update(tbl); //update the table
this.fnRefresh(); //refresh the table
}
}
从 XML 文件读取数据
有时您必须从 XML 文件读取数据并将其显示在 DataGrid
中。为了做到这一点,我将 XML 文件传递给该方法;如果文件存在,我将清除 DataSet
并使用指定的文件将 XML 数据读入 DataSet
。以下代码片段显示了这一点
private void fnDataReadingFromXMLFile(string filename)
{
//check if the file exists
if ( File.Exists(filename))
{
//clear the DataSet contents
this.dataSet11.Clear();
MessageBox.Show("Data reading from "+filename+" -file");
this.dataSet11.ReadXml(filename);
} //if
else {
MessageBox.Show(filename + " does NOT exist; Please click" +
" first the button 'CopyToXML' ", "File Error",
MessageBoxButtons.OK, MessageBoxIcon.Error );
}//else
}
将 DataSet 复制到文本/XML/架构文件
单击“CopyToXML”按钮将调用“fnCopyToXMLandTextFile()
”方法。正如您从其名称中可以猜到的,它将 DataSet
的当前数据写入 C:\ 根目录下的三个文件
- 文本文件:MyXMLdataText.txt。
- XML 文件:XMLdata.xml。
- 架构文件:MyXMLschema.xsd。
如果您希望使用其他路径而不是“C:\”,则必须相应地更改代码。以下代码片段演示了此功能
private void fnCopyToXMLandTextFile()
{
if (this.dataSet11 == null)
{
return; //cancel
}
files. this.dataSet11.WriteXml("C:\\MyXMLText.txt");
this.dataSet11.WriteXml("C:\\MyXMLdata.xml", XmlWriteMode.WriteSchema);
this.dataSet11.WriteXmlSchema("C:\\MyXMLschema.xsd");
string s="The current data of the DataSet coppied on C:\\ as: \n";
s +="* Text file: MyXMLdataText.txt\n";
s +="* XML file: XMLdata.xml\n";
s +="* Schema file: MyXMLschema.xsd";
MessageBox.Show(s, "Copy to XML/Text/Schema file");
}
将表的当前数据写入硬盘(C:\)上的文本文件
因为 ExecuteReader
需要一个打开且可用的连接,所以我们首先必须打开数据库连接。如果连接的当前状态是 Closed
,您会收到错误消息。打开连接后,我们创建 OleDbCommand
的实例、SQL 语句的 CommandText
、OleDbDataReader
和 StreamWriter
的实例。然后,在 while
循环中,OleDbDataReader
读取数据行并将它们写入文本文件。最后,它关闭 OleDbDataReader
。在 StreamWriter writer = new StreamWriter("C:\\MyTextFile.txt", false)
中,我们传递文本文件并将 bool
值设置为“false
”。如果文件不存在,无论如何都会创建一个新的文本文件。如果文件存在并且第二个参数是“false
”,则文件将被覆盖,因为是“false
”。如果值为“true
”,则文件不会被覆盖,数据将附加到文件中。以下是写入文本文件的代码片段
private void fnWriteToTextFile()
{
OleDbDataReader reader;
OleDbCommand cmd=new OleDbCommand();
this.oleDbConnection1.Open(); //open the connection
cmd.CommandText="SELECT Address, City, Country, Email," +
" FirstName, LastName, Message, Phone FROM MyContactsTable";
cmd.Connection=this.oleDbConnection1;
reader=cmd.ExecuteReader();
//the "using" statement causes the close method to be called internally.
//if "using" not used, use "writer.Close()" in try-catch-finally explicitly
using (StreamWriter writer = new StreamWriter("C:\\MyTextFile.txt",false))
{
//false means: textfile is overwritten
try
{
while (reader.Read())
{
writer.Write(reader["LastName"]);
writer.Write("#"); //separator
writer.Write(reader["FirstName"]);
writer.Write("#");
writer.Write(reader["Address"]);
writer.Write("#");
writer.Write(reader["City"]);
writer.Write("#");
writer.Write(reader["Country"]);
writer.Write("#");
writer.Write(reader["Email"]);
writer.Write("#");
writer.Write(reader["Message"]);
writer.Write("#");
writer.Write(reader["Phone"]);
writer.WriteLine(); //next new line
}//while
}catch (Exception excp)
{
MessageBox.Show(excp.Message);
}finally {
reader.Close(); //close the OleDbDataReader
}//try-catch-finally
}//using
MessageBox.Show("Data of table writtten into" +
" C:\\MyTextFile.txt file","Writing completed");
}
最后
我认为代码非常简单易懂,因为我尝试在几乎每行代码中都添加注释。希望您能在这里为您的项目找到一些有用的东西。一如既往,欢迎所有反馈。有关 DataGrid
的更多提示,请参阅我的另一篇文章链接:面向初学者的 ADO.NET 使用指南。
祝您编码愉快!