C#WinForm基础编程(三)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: C#WinForm基础编程

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;//让学生编号列隐藏
}


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
20天前
|
C# 开发者
C# 一分钟浅谈:Code Contracts 与契约编程
【10月更文挑战第26天】本文介绍了 C# 中的 Code Contracts,这是一个强大的工具,用于通过契约编程增强代码的健壮性和可维护性。文章从基本概念入手,详细讲解了前置条件、后置条件和对象不变量的使用方法,并通过具体代码示例进行了说明。同时,文章还探讨了常见的问题和易错点,如忘记启用静态检查、过度依赖契约和性能影响,并提供了相应的解决建议。希望读者能通过本文更好地理解和应用 Code Contracts。
30 3
|
2月前
|
SQL API 定位技术
基于C#使用winform技术的游戏平台的实现【C#课程设计】
本文介绍了基于C#使用WinForms技术开发的游戏平台项目,包括项目结构、运行截图、实现功能、部分代码说明、数据库设计和完整代码资源。项目涵盖了登录注册、个人信息修改、游戏商城列表查看、游戏管理、用户信息管理、数据分析等功能。代码示例包括ListView和ImageList的使用、图片上传、图表插件使用和SQL工具类封装,以及高德地图天气API的调用。
基于C#使用winform技术的游戏平台的实现【C#课程设计】
|
1月前
|
设计模式 程序员 C#
C# 使用 WinForm MDI 模式管理多个子窗体程序的详细步骤
WinForm MDI 模式就像是有超能力一般,让多个子窗体井然有序地排列在一个主窗体之下,既美观又实用。不过,也要小心管理好子窗体们的生命周期哦,否则一不小心就会出现一些意想不到的小bug
106 0
|
2月前
|
API C#
C# 一分钟浅谈:文件系统编程
在软件开发中,文件系统操作至关重要。本文将带你快速掌握C#中文件系统编程的基础知识,涵盖基本概念、常见问题及解决方法。文章详细介绍了`System.IO`命名空间下的关键类库,并通过示例代码展示了路径处理、异常处理、并发访问等技巧,还提供了异步API和流压缩等高级技巧,帮助你写出更健壮的代码。
45 2
|
1月前
|
安全 C# 数据安全/隐私保护
实现C#编程文件夹加锁保护
【10月更文挑战第16天】本文介绍了两种用 C# 实现文件夹保护的方法:一是通过设置文件系统权限,阻止普通用户访问;二是使用加密技术,对文件夹中的文件进行加密,防止未授权访问。提供了示例代码和使用方法,适用于不同安全需求的场景。
115 0
|
2月前
|
安全 程序员 编译器
C#一分钟浅谈:泛型编程基础
在现代软件开发中,泛型编程是一项关键技能,它使开发者能够编写类型安全且可重用的代码。C# 自 2.0 版本起支持泛型编程,本文将从基础概念入手,逐步深入探讨 C# 中的泛型,并通过具体实例帮助理解常见问题及其解决方法。泛型通过类型参数替代具体类型,提高了代码复用性和类型安全性,减少了运行时性能开销。文章详细介绍了如何定义泛型类和方法,并讨论了常见的易错点及解决方案,帮助读者更好地掌握这一技术。
79 11
|
2月前
|
SQL 开发框架 安全
并发集合与任务并行库:C#中的高效编程实践
在现代软件开发中,多核处理器普及使多线程编程成为提升性能的关键。然而,传统同步模型在高并发下易引发死锁等问题。为此,.NET Framework引入了任务并行库(TPL)和并发集合,简化并发编程并增强代码可维护性。并发集合允许多线程安全访问,如`ConcurrentQueue&lt;T&gt;`和`ConcurrentDictionary&lt;TKey, TValue&gt;`,有效避免数据不一致。TPL则通过`Task`类实现异步操作,提高开发效率。正确使用这些工具可显著提升程序性能,但也需注意任务取消和异常处理等常见问题。
48 1
|
1月前
|
API C# Windows
【C#】在winform中如何实现嵌入第三方软件窗体
【C#】在winform中如何实现嵌入第三方软件窗体
92 0
|
1月前
|
API C#
C#实现Winform程序右下角弹窗消息提示
C#实现Winform程序右下角弹窗消息提示
85 0
下一篇
无影云桌面