估计这类文章烂大街都是,然而,这个基础又经典的程序不仿一写再写。如下图,新建一个C#窗体程序之后,先在工程相应的运行目录中新建一个Access2003数据库:
Access2003里面有一张如下图的user表,其中id是自增项,username与password皆为文本项。
我们完成如下的一个程序,实现对这张表的增删改查。
注意到,如果你在列表视图,也就是listview中没有选定项的话,点击N次修改、删除按钮是没有效果的。
程序完成之后,Access2003中的user自然也会做相应的修改:
这个程序的制作过程如下:
1、首先是整个程序的文件树:
Intent.cs是用于主窗体Form1.cs与Form2.cs之间传值的,在《【C#】窗体间互相传值》(点击打开链接)一文中详细说过了,就一个存放东西的字典容器,这里不再赘述了,具体代码如下:
using System; using System.Collections.Generic; using System.Text; namespace toAccess { class Intent { public static Dictionary<string, Object> dict = new Dictionary<string, Object>(); } }
之后form1.cs的代码如下,讲述了C#的ListView是如何使用的,同时如何对Access数据库做增删改查的,这里需要特别注意的几点:
(1)System.Environment.CurrentDirectory可以取到程序当前的路径
(2)用到数据库连接,在头文件要添加using System.Data.OleDb;的引用
(3)listview的每一行的第一项与其余子项的添加是不同的
(4)listview的选中项修改、删除之后的更变问题,导致对listview选中项的操作与对数据库操作是有先后问题的。
(5)判断listview是否有项被选中,用if (listView1.SelectedItems.Count > 0)
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Data.OleDb; namespace toAccess { public partial class Form1 : Form { OleDbConnection oleDbConnection = new OleDbConnection("Provider=Microsoft.Jet.OleDb.4.0;Data Source=" + System.Environment.CurrentDirectory + "\\Database.mdb;Jet OleDb:DataBase Password=admin;"); //数据库连接的声明 public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { //设置listview的表头 listView1.Columns.Add("序号", listView1.Width / 3 - 1, HorizontalAlignment.Left); listView1.Columns.Add("用户名", listView1.Width / 3 - 1, HorizontalAlignment.Left); listView1.Columns.Add("密码", listView1.Width / 3 - 1, HorizontalAlignment.Left); oleDbConnection.Open();//打开数据库 try { string sql = "select * from [user]"; OleDbDataReader oleDbDataReader = new OleDbCommand(sql, oleDbConnection).ExecuteReader(); listView1.BeginUpdate();//数据更新,UI暂时挂起,直到EndUpdate绘制控件,可以有效避免闪烁并大大提高加载速度 for (int i = 1; oleDbDataReader.Read(); i++)//遍历查询结果 { ListViewItem listViewItem = new ListViewItem(); listViewItem.Text = i + "";//listview的每一行的第一项 listViewItem.SubItems.Add(oleDbDataReader.GetString(1));//其余子项 listViewItem.SubItems.Add(oleDbDataReader.GetString(2)); listView1.Items.Add(listViewItem);//将这行添加到listview中 } listView1.EndUpdate();//结束数据处理,UI界面一次性绘制。 } catch { MessageBox.Show(this.Text, "数据库出错!"); } } private void button1_Click(object sender, EventArgs e) { Form2 form2 = new Form2();//声明要使用form2窗体 //将form1当前的位置压入Intent中的dict Intent.dict["form1_text"] = this.Text; Intent.dict["form1_flag"] = 0;//传个flag进去代表这是“添加” if (form2.ShowDialog() == DialogResult.OK) {//这个判断,将会等到form2被关闭之后才执行,如果form2返回一个OK值 ListViewItem listViewItem = new ListViewItem();//在listview中添加一项 listViewItem.Text = (listView1.Items.Count + 1) + ""; listViewItem.SubItems.Add(Intent.dict["form2_textbox1_text"] + ""); listViewItem.SubItems.Add(Intent.dict["form2_textbox2_text"] + ""); listView1.Items.Add(listViewItem); try { string sql = "insert into [user]([username],[password]) values('" + Intent.dict["form2_textbox1_text"] + "','" + Intent.dict["form2_textbox2_text"] + "');"; new OleDbCommand(sql, oleDbConnection).ExecuteNonQuery();//无返回值的sql语句用这个方法 } catch { MessageBox.Show("数据库出错!", this.Text); } } } private void button2_Click(object sender, EventArgs e) { if (listView1.SelectedItems.Count > 0) { Form2 form2 = new Form2();//声明要使用form2窗体 //将form1当前的位置压入Intent中的dict Intent.dict["form1_text"] = this.Text; Intent.dict["form1_selectedItems_username"] = listView1.SelectedItems[0].SubItems[1].Text; Intent.dict["form1_selectedItems_password"] = listView1.SelectedItems[0].SubItems[2].Text; Intent.dict["form1_flag"] = 1;//传个flag进去代表这是“修改” if (form2.ShowDialog() == DialogResult.OK) {//这个判断,将会等到form2被关闭之后才执行,如果form2返回一个OK值 try { string sql = "update [user] set [username]='" + Intent.dict["form2_textbox1_text"] + "' where [username]='" + Intent.dict["form1_selectedItems_username"] + "';"; new OleDbCommand(sql, oleDbConnection).ExecuteNonQuery();//无返回值的sql语句用这个方法 sql = "update [user] set [password]='" + Intent.dict["form2_textbox2_text"] + "' where [password]='" + Intent.dict["form1_selectedItems_password"] + "';"; new OleDbCommand(sql, oleDbConnection).ExecuteNonQuery();//无返回值的sql语句用这个方法 } catch { MessageBox.Show("数据库出错!", this.Text); } //修改的话,数据库修改语句应该放在窗体选中项处理之前,当然可以直接取Intent的值进行操作 listView1.SelectedItems[0].SubItems[1].Text = Intent.dict["form2_textbox1_text"] + ""; listView1.SelectedItems[0].SubItems[2].Text = Intent.dict["form2_textbox2_text"] + ""; } } } private void button3_Click(object sender, EventArgs e) { if (listView1.SelectedItems.Count > 0) { DialogResult dialogResult = MessageBox.Show( "确定删除序号为:" + listView1.SelectedItems[0].Text + "," + "用户名为:" + listView1.SelectedItems[0].SubItems[1].Text + "密码为:" + listView1.SelectedItems[0].SubItems[2].Text + "的项吗?", this.Text, MessageBoxButtons.YesNo); if (dialogResult == DialogResult.Yes) { try { string sql = "delete from [user] where [username]='" + listView1.SelectedItems[0].SubItems[1].Text + "' and [password]='" + listView1.SelectedItems[0].SubItems[2].Text + "';"; new OleDbCommand(sql, oleDbConnection).ExecuteNonQuery();//无返回值的sql语句用这个方法 listView1.SelectedItems[0].Remove();//删除一定要放在数据库操作之后,不然选中项再也取不到了 for (int i = 1; i <= listView1.Items.Count; i++) {//更新序号 listView1.Items[i - 1].SubItems[0].Text = i + ""; } } catch { MessageBox.Show("数据库出错!", this.Text); } } } } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { oleDbConnection.Close(); } } }
form2.cs的代码如下,这个添加与修改的填出框,通过form1传过来的Intent.dict["form1_flag"],作相应的初始化,接着完成,将用户对两个文本框的输入内容传到form1的任务就好,其余一切form1.cs做完。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace toAccess { public partial class Form2 : Form { public Form2() { InitializeComponent(); } private void Form2_Load(object sender, EventArgs e) { if ((int)Intent.dict["form1_flag"] == 0) { this.Text = Intent.dict["form1_text"] + ""; textBox1.Focus();//设置焦点停留在textBox1中 } else { this.Text = Intent.dict["form1_text"] + ""; textBox1.Text = Intent.dict["form1_selectedItems_username"] + ""; textBox2.Text = Intent.dict["form1_selectedItems_password"] + ""; textBox1.Focus();//设置焦点停留在textBox1中 textBox1.SelectAll();//要先有焦点才能全选 } } private void button1_Click(object sender, EventArgs e) { //关闭form2之间,将要传给form1的值压入Intent中的dict Intent.dict["form2_textbox1_text"] = textBox1.Text; Intent.dict["form2_textbox2_text"] = textBox2.Text; this.DialogResult = DialogResult.OK;//同时设置返回值为OK,不设置的话,默认返回Cancel this.Close(); } private void button2_Click(object sender, EventArgs e) { this.Close();//直接关闭,同点关闭按钮,返回值为Cancel } } }
如果还不行,可以先下载运行 AccessDatabaseEngine_x64.exe(http://www.microsoft.com/downloads/en/details.aspx?FamilyID=c06b8369-60dd-4b64-a44b-84b371ede16d&displaylang=en)然后,如下代码,关于链接数据库部分将连接字符串改成:Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=mdb.mdb;uid=admin;pwd=password;的形式。