估计这类文章烂大街都是,然而,这个基础又经典的程序不仿一写再写。如下图,新建一个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 dict = new Dictionary();
}
}
之后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;的形式。