C#WinForm基础编程(二)https://developer.aliyun.com/article/1433701
第六章:winform界面
第一节:名词解释
partial:部分的,指目前创建的类为部分类,只有当两个partial类合在一起才能起到应有的作用:
Form:窗体类,其中Form1 : Form是继承的意思
第二节:窗体的属性
name : btn_plus,txt_num1
text: 界面上显示的文本
backgroundimage: 添加背景图片
FormBorderStyle: FixedSingler,定义边界可否改变
maxinimizeBox: 最大化按钮
StartPosition:窗体起始位置
WindowState:窗体初始化的状态,最小化、一般状态、最大化状态
获得文本框的值:txt_num1.Text
转换成数字:int.Parse(txt_num1.Text);double.Parse(txt_num1.Text)
第三节:窗体的事件
click;load;FormClosing; keyDown;
第四节:常用控件
Button
TextBox
RadioButton
DateTimePicker
dateTimePicker1.Value = DateTime.Parse(“2010-10-29”);
Panel布局面板,Dock属性
三元表达式:
变量=表达式?第一个值:第二个值;
/*if (radMan.Checked == true) { sex = "男"; } else { sex = "女"; }*/ //string sex = radMan.Checked?"男":"女"; MessageBox.Show(radMan.Checked ? "男":"女");
Timer和PictureBox
示例:实现Tomcat动画,原理就是在PictureBox中每间隔100毫秒加载一次图片,让图片框中显示动画效果。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8odOs8i3-1672665634025)(assets\1551430051109.png)]
代码:
private void btn_start_Click(object sender, EventArgs e) { timer1.Start(); } int count = 0; private void timer1_Tick(object sender, EventArgs e) { picbox.Image = Image.FromFile("angry/angry_"+count+".jpg");//获得文件中的图片 count++; if (count > 25) { count = 0; } } private void button1_Click(object sender, EventArgs e) { timer1.Stop(); }
第五节:消息对话框
MessageBox.Show(“内容信息”,“标题”,MessageBoxButton.YesNo,MessageBoxIcon.Question);
MessageBox的返回值:DialogResult.OK;Cancel;Yes;No
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qd2yx96N-1672665634027)(assets\1551421875230.png)]
DialogResult res= MessageBox.Show("你真的要退出程序么?","提示", MessageBoxButtons.YesNo,MessageBoxIcon.Question); if (res == DialogResult.Yes) { e.Cancel = false; } else { e.Cancel = true; }
第五节:菜单
1、固定菜单:MenuStrip
2、右键菜单:ContextMenuStrip
第四节:界面传值
要打开的窗体代码
public partial class Form2 : Form { public string name;//在要打开的页面中声明一个共有的变量用来接收数据 public Form2() { InitializeComponent(); } private void Form2_Load(object sender, EventArgs e)//窗体加载事件 { labName.Text = name;//将接收到的数据在labName标签上显示 } }
第一个窗体中打开第二个窗体的代码
Form2 form = new Form2(); form.name = txtName.Text;//将本窗体文本框的文本值赋值给要打开窗体的共有属性name form.Show();
第五节:运行指定窗体
测试或练习时经常要直接运行某一个窗体,如果从菜单处一级级打开太麻烦,可以直接修改主程序代码来完成。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YqSQJcOv-1672665634028)(assets\1551419630842.png)]
修改Main中最后一句代码:Application.Run(new Form1());将Run()中的窗体换成要运行的窗体就可以了。
第六节:主从窗体
主窗体的isMdiContainer属性设置成true,在打开子窗体的代码中,设置子窗体的MdiParent=this;
Form2 fm = new Form2(); fm.Show(); fm.MdiParent = this;
视频课:https://edu.51cto.com/course/20906.html
第七章:连接数据库
第一节:ADO.NET的结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H8KIEpxy-1672665634030)(assets\1551491971415.png)]
数据库访问的顺序:
1)建立数据库连接
2)打开数据库连接
3)编写SQL语句
4)创建SQL命令对象SQLCommand
5)执行SQL命令
6)关闭数据库连接
示例1:添加班级信息
string constr="server=localhost;userid=root;password=root; database=school"; MySqlConnection conn = new MySqlConnection(constr);//创建数据库连接对象 conn.Open();//打开连接对象 string className = txtClassName.Text; string createDate = txtCreateDate.Text; string sql =string.Format("insert into classes(className,createDate) values('{0}','{1}')",className,createDate); MySqlCommand command = new MySqlCommand(sql,conn);//根据sql命令和数据库连接创建数据库命令对象 int count=command.ExecuteNonQuery();//执行数据库的非查询命令 if (count > 0)//如果返回值(影响的行数)大于0,提示录入成功 { MessageBox.Show("班级录入成功"); } conn.Close();//关闭数据库连接
第二节:DataSet结构
1)数据集合的作用:是在内存中建立起一个临时的数据仓库,可以对其进行操作并同步到底层数据库。
2)数据集结构:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oVU4eVax-1672665634032)(assets\1551507101167.png)]
3)使用DataTable
有行和列的集合:Columns和Rows,
Rows就是查询获得的数据表中的每一行数据集合,集合就可以通过索引或下标访问,例如:通过Rows【1】【“班级名称” 】获得该数据,
Columns是表格中列的集合,通过Columns【“身份证号码”】来获得指定的列对象
4)DataGridView
常用属性:
DataSource:数据源,可以设置某一个DataTable即可
SelectionMode:是表格的选择模式,一般选择FullRowSelect
MultiSelect:是否可以多选
ReadOnly:是否只读
添加该控件后顺手把它的这几个选项如图选定,一般不在表格中进行添加和修改操作。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rR0T4U3K-1672665634033)(assets\1551505590554.png)]
示例2:数据查询
查询使用数据适配器MySQLDataAdapter,用法和MySqlCommand相同,该适配器可以填充一个内存中的表格DataTable对象,然后让dataGradView的数据源(DataSource)指向该表格。
string connstr = "server=localhost;userid=root;password=root; database=school"; MySqlConnection conn = new MySqlConnection(connstr); string sql ="select buildId 宿舍楼编号,buildName 宿舍楼名称 from building ";//查询宿舍楼的所有信息 MySqlDataAdapter adapter = new MySqlDataAdapter(sql,conn);//创建数据适配器 DataTable dt = new DataTable();//创建内存中数据表格 adapter.Fill(dt);//使用适配器将查询后的数据填充到内存的数据表中 dgvBuild.DataSource = dt;//将dataGradView的数据源指向内存中的数据表
示例3:数据库通用代码
class DBHelper { public static string constr = "server=localhost;user id=root; password=root; database=school"; public static MySqlConnection getConnection() { MySqlConnection conn = new MySqlConnection(constr); conn.Open(); return conn; } public static void close(MySqlConnection conn) { if (conn != null) { conn.Close(); conn = null; } } public static int update(string sql) { MySqlConnection conn = getConnection(); MySqlCommand command = new MySqlCommand(sql, conn); int count = command.ExecuteNonQuery(); conn.Close(); return count; } public static DataTable query(string sql) { MySqlConnection conn = getConnection(); DataTable dt = new DataTable(); MySqlDataAdapter adapter = new MySqlDataAdapter(sql,conn); adapter.Fill(dt); return dt; } }
示例3:使用通用类的方法完成添加和查询
string className = txtClassName.Text; string createDate = dtpCreateClasses.Text; string sql = string.Format()"insert into classes(className,createDate) values('{0}','{1}')",className,createDate); DBHelper.update(sql); sql = "select classId 班级编号,className 班级名称,createDate 开班日期 from classes order by classId desc"; DataTable dt = DBHelper.query(sql); dgvClass.DataSource = dt;
示例4:使用通用方法完成向comboBox中添加班级信息
string sql = "select classId,className from classes"; DataTable dt = DBHelper.query(sql); //MessageBox.Show(dt.Rows[0]["className"].ToString()); foreach(DataRow row in dt.Rows) {//rows是dataTable的行的集合,可以通过下标来访问 combDormType.Items.Add(row["className"].ToString()); }//某一行中有sql中查询的字段信息可以通过dt.Rows[i]["字段名"]来访问 combDormType.SelectedIndex = 0;//设置下拉框默认选中第一个选项
示例5:将班级对象加入到comboBox中
创建Classes类
class Classes { public int classId; public string className; public Classes(int classId,string className) { this.classId = classId; this.className = className; } public Classes() { } override//表示该方法是覆盖父类的方法,用来显示该类的对象 public string ToString() { return className; } }
示例6:改造加入comboBox的代码,将classes对象加入到comboBox中
DataTable dt = DBHelper.query("select * from classes"); foreach(DataRow row in dt.Rows) { Classes cla = new Classes((int)row[0],row[1].ToString()); combClass.Items.Add(cla);//将classes对象放入到组合框中 } combClass.SelectedIndex = 0;
示例7:测试comboBox中选中的对象的classId和className 数据,在comboBox的selectedIndexChange事件中执行如下代码:
Classes cla = (Classes)combDormType.SelectedItem; MessageBox.Show(cla.classId+":"+cla.className);
视频课:https://edu.51cto.com/course/20906.html
第八章:数据修改
数据修改不能直接像录入一样在界面填入数据,只能先查询出数据,选定某条数据后点击修改按钮,将该条数据显示在一个类似于录入界面的窗体中再进行修改,修改过的数据再点击确定最后修改到数据库,需要的话再刷新查询数据。
一、查询出班级数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-95yqwsiF-1672665634034)(assets\1545980685501.png)]
二、点击修改按钮、创建修改窗体
示例 1:
string classId = dgvClass.SelectedRows[0].Cells[0].Value.ToString();//获得表格中选中的第一行的第一个单元的值,付给classId; FmClassUpdate fcu = new FmClassUpdate(); fcu.classId = classId;//给FMClassUpdate窗体中的classId属性赋值 fcu.ShowDialog();//以模态窗体的形式显示修改窗体 fcu.MdiParent = this.MdiParent;//将修改窗体的父窗体设置为主窗体
三 、在修改窗体的load事件中根据传进来的classId查询班级信息,并将班级信息填入相应的组件中。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mu3h6TYX-1672665634035)(assets\1545980731301.png)]
string sql = "select className,createDate from classes where classId="+classId; DataTable dt = DBHelper.query(sql); txtClassName.Text= dt.Rows[0]["className"].ToString();//给文本框赋值成查询的班级名称 dtpClassDate.Value =(DateTime)dt.Rows[0]["createDate"];
四、在修改窗体中点击修改按钮
string sql = string.Format("update classes set className='{0}', createDate='{1}' where classId={2}",txtClassName.Text,dtpClassDate.Text , classId); int count = DBHelper.update(sql); if (count > 0) { Close(); }else { MessageBox.Show("修改错误","提示"); }
五、学生入住
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U0g24v1P-1672665634036)(assets\1545980598202.png)]
界面中按照班级查询出要入住的学生,在左侧选定要进入的宿舍,选定入住的学生(多选)点击入住完成操作,如果选中的人数大于可以入住的空位,则要提示人数太多,
//获得左边选中宿舍的编号,注意宿舍编号列是隐藏的在第一位cells[0] string dormId = dgvDorm.SelectedRows[0].Cells[0].Value.ToString() ; string stuId = ""; string sql = ""; //获得目前该宿舍中已经入住的人数,以便判断选中的学生人数是否超过该宿舍的额定人数 sql = "select count(*) dormCount from student where fk_dormId="+dormId; DataTable dtCount = DBHelper.query(sql); //Console.WriteLine(dtCount.Rows[0]); int dormCount =int.Parse( dtCount.Rows[0].ToString()); //查询该宿舍最多能住的人数 sql = "select perCount from dorm,dormType where fk_dormTypeId=typeId and dormId="+dormId; DataTable dtPerCount = DBHelper.query(sql); int perCount = (int)dtPerCount.Rows[0]; if (perCount - dormCount >= dgvStudent.SelectedRows.Count) { for(int i = 0; i < dgvStudent.SelectedRows.Count; i++) {//将选中的学生逐个加入到选定的宿舍(修改学生的宿舍外键为该宿舍的) stuId = dgvStudent.SelectedRows[i].Cells["编号"].Value.ToString(); sql = string.Format("update student set fk_dormId={0} where stuId={1}",dormId,stuId); DBHelper.update(sql); } //将该宿舍中已经有的学生显示到dgvDormStudent表格中 sql = "select stuId 学生编号,stuName 学生姓名 from student where fk_dormId="+dormId; DataTable dt = DBHelper.query(sql); dgvDormStudent.DataSource = dt; btnStuQuery_Click(sender, e);//调用学生查询按钮的方法 }else { MessageBox.Show("宿舍住不下这么多人,请重新选择!","提示"); }
学生按条件查询,如果没有输入条件则按照所有的查询
public void queryStudent() { string sql = "select stuId, stuName 姓名,student.sex 性别,idcard 身份证,telPhone 电话,city 城市,className 班级,dormName 宿舍 from student join classes on classId=fk_classId left join dorm on fk_dormId=dormId"; if (txtName.Text != "") { sql += string.Format(" and stuName like '%{0}%'", txtName.Text); } if (txtClassName.Text != "") { sql += string.Format(" and className like '%{0}%'", txtClassName.Text); } if (txtCity.Text != "") { sql += string.Format(" and city = '{0}'", txtCity.Text); } dgvStudent.DataSource = DBHelper.query(sql); dgvStudent.Columns["身份证"].Width = 200;//让身份证那一列宽度加大 dgvStudent.Columns["stuId"].Visible = false;//让学生编号列隐藏 }
if (perCount - dormCount >= dgvStudent.SelectedRows.Count) { for(int i = 0; i < dgvStudent.SelectedRows.Count; i++) {//将选中的学生逐个加入到选定的宿舍(修改学生的宿舍外键为该宿舍的) stuId = dgvStudent.SelectedRows[i].Cells[“编号”].Value.ToString(); sql = string.Format(“update student set fk_dormId={0} where stuId={1}”,dormId,stuId); DBHelper.update(sql); } //将该宿舍中已经有的学生显示到dgvDormStudent表格中 sql = “select stuId 学生编号,stuName 学生姓名 from student where fk_dormId=”+dormId; DataTable dt = DBHelper.query(sql); dgvDormStudent.DataSource = dt; btnStuQuery_Click(sender, e);//调用学生查询按钮的方法 }else { MessageBox.Show(“宿舍住不下这么多人,请重新选择!”,“提示”); }
学生按条件查询,如果没有输入条件则按照所有的查询
public void queryStudent() { string sql = "select stuId, stuName 姓名,student.sex 性别,idcard 身份证,telPhone 电话,city 城市,className 班级,dormName 宿舍 from student join classes on classId=fk_classId left join dorm on fk_dormId=dormId"; if (txtName.Text != "") { sql += string.Format(" and stuName like '%{0}%'", txtName.Text); } if (txtClassName.Text != "") { sql += string.Format(" and className like '%{0}%'", txtClassName.Text); } if (txtCity.Text != "") { sql += string.Format(" and city = '{0}'", txtCity.Text); } dgvStudent.DataSource = DBHelper.query(sql); dgvStudent.Columns["身份证"].Width = 200;//让身份证那一列宽度加大 dgvStudent.Columns["stuId"].Visible = false;//让学生编号列隐藏 }