本文代码仓库地址: gitee码云CSDN笔记仓库地址


一、先新建项目,找到Windows窗体应用(.net Framework)
在这里插入图片描述
在这里插入图片描述

二、在窗体上面拖控件

1.主窗体
控件:
splitContainer:设置父窗体停靠
treeView:放在splitContainer的panel1上面设置父窗体停靠,然后编辑节点,添加几个节点,按照自己的命名设置相关的属性;还可以设置【ShowLine: False】去掉前面的线,设置字体行间距啥的,【FullRowSelect: True】设置为满行选择

2.新建一个窗体
控件:groupBoxlabel*2、TextBoxcomboBoxcheckBox1buttondataGridViewcontextMenuStrip

  • contextMenuStrip是鼠标右键弹出选项的控件,里面需要添加一些自己设置右键弹出的内容,在那种情况下弹出和不弹出具体代码里面都有注释
  • 可以适当的设置他们的Anchor属性,在父窗体改变形状的时候会有用
  • 这个窗体我们是需要让其在主窗体里面显示,这里需要设置主窗体属性【isMdiContainer: True; 是设置为可以承载子窗体的一个父窗体】
  • 设置完主窗体设置本窗体属性【FormBorderStyle: None; 设置窗体为无边框窗体、WindowState: Maximized; 设置窗体显示时 为最大化】
    其中 dataGridView 的列设置为复选框的样式的设置如下图
    在这里插入图片描述

主窗体代码代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp_xiaoyin01 {
  public partial class FrmMain_xy : Form {
    public FrmMain_xy()
    {
      InitializeComponent();
    }

    private void FrmMain_xy_Load(object sender, EventArgs e)
    {
      /* FrmMain_xy 窗体属性设置
       * isMdiContainer: True; 是设置为可以承载子窗体的一个父窗体
       *
       */
      FrmUserManager_xy FrmUserManager = new FrmUserManager_xy();
      // 他的 父MDI 为当前这个窗体
      FrmUserManager.MdiParent = this;
      // 他的父容器为 splitContainer1.Panel2
      FrmUserManager.Parent = splitContainer1.Panel2;
      // 显示在这个窗体容器中不能用 ShowDialog
      FrmUserManager.Show();
      // 模式显示窗体 FrmUserManager_xy(在窗体以外显示)
      // FrmUserManager.ShowDialog();
    }

    private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
    {
      // 选择了某项后出发的事件
      // 每次选择节点前恢复之前的默认设置
      foreach (TreeNode node in treeView1.Nodes)
      {
        node.BackColor = Color.White;
        node.ForeColor = Color.Black;
      }
      // 设置选择的节点背景颜色为系统色高亮
      e.Node.BackColor = SystemColors.Highlight;
      // 设置前景色为白色
      e.Node.ForeColor = Color.White;
    }
  }
}

在这里插入图片描述


在看子窗体代码之前先写好 SQLHelper 文件:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WindowsFormsApp_xiaoyin01.Utility {
  class SqlHelper {
    public static string ConStr { get; set; }

    /// <summary>
    /// SQL 查询操作
    /// </summary>
    /// <param name="sqlTxt">SQL语句</param>
    /// <returns>查询到的数据</returns>
    public static DataTable ExecuteTable(string sqlTxt)
    {
      // using:可以自动释放资源;SqlConnection:SQL连接
      using (SqlConnection conn = new SqlConnection(ConStr))
      {
        // 打开数据库
        conn.Open();
        // SQL命令的执行【conn就相当于执行的上方宝剑】(cmd 是管理员)
        SqlCommand cmd = new SqlCommand(sqlTxt, conn);
        // SQL适配器 (sda 是小推车,管理员推车小推车)
        SqlDataAdapter sda = new SqlDataAdapter(cmd);
        // 数据集 (ds 相当于汽车)
        DataSet ds = new DataSet();
        // 管理员把小推车里面的数据放进汽车里面
        sda.Fill(ds);
        // 到家后 拿出车上序号为 0 的数据进行返回
        return ds.Tables[0];
      }
    }

    /// <summary>
    /// SQL 增、删、改操作
    /// <param name="sqlTxt">SQL语句</param>
    /// </summary>
    /// <returns>受影响行数</returns>
    public static int ExecuteNonQuery(string sqlTxt)
    {
      // using:可以自动释放资源;SqlConnection:SQL连接
      using (SqlConnection conn = new SqlConnection(ConStr))
      {
        // 打开数据库
        conn.Open();
        // SQL命令的执行【conn就相当于执行的上方宝剑】(cmd 是管理员)
        SqlCommand cmd = new SqlCommand(sqlTxt, conn);
        // 返回受影响的行数
        int row = cmd.ExecuteNonQuery();
        if (row <= 0)
        {
          // 当没有受影响的行数时,返回的错误提示
          throw new Exception("亲,没有受影响的行数哦!!!");
        }
        return row;
      }
    }
    
  }
}

打开 App.config 文件:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
	<connectionStrings>
		<!-- 添加一个节点 connectionStrings:连接字符串   Data Source:数据库ip,database:数据库名称,uid:数据库账号,pwd:数据库密码 -->
		<add name="ConStr" connectionString="Data Source=127.0.0.1; database=yin; uid=sa; pwd=YINhui1998"/>
	</connectionStrings>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
    </startup>
</configuration>

自己新建的子窗体代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WindowsFormsApp_xiaoyin01.Models;

namespace WindowsFormsApp_xiaoyin01 {
  public partial class FrmUserManager_xy : Form {
    public FrmUserManager_xy()
    {
      InitializeComponent();
    }

    private void FrmUserManager_xy_Load(object sender, EventArgs e)
    {
      BindCbx();
      BindDgv();
    }

    private void BindDgv()
    {
      // 通过下面三个字段进行筛选
      string userName = TextBox1.Text.Trim();
      int baseTypeId = (int)comboBox1.SelectedValue;
      bool isStop = checkBox1.Checked;
      // 取消自动填充数据【没有手动添加的数据不会生成新的列】
      dataGridView1.AutoGenerateColumns = false;
      List<UserAppraisalBases> userAppraisalBases01 = UserAppraisalBases.GetListJoinAppraisal();
      if (baseTypeId == 0)
      {
        dataGridView1.DataSource = userAppraisalBases01.FindAll(m => m.UserName.Contains(userName) && m.IsDel == isStop);
      }
      else
      {
        dataGridView1.DataSource = userAppraisalBases01.FindAll(m => m.UserName.Contains(userName) && m.BaseTypeld == baseTypeId && m.IsDel == isStop);
      }
    }

    /// <summary>
    /// 绑定 comboBox1 ,向 comboBox1 中添加数据
    /// </summary>
    private void BindCbx()
    {
      /* FrmUserManager_xy 窗体设置
       * FormBorderStyle: None; 设置窗体为无边框窗体
       * WindowState: Maximized; 设置窗体显示时 为最大化
       **/
      List<AppraisalBases_xy> AppraisalBases = new List<AppraisalBases_xy>();
      AppraisalBases.Add(new AppraisalBases_xy
      {
        Id = 0,
        BaseType = "-查询所有-",
        AppraisalBase = 0,
        IsDel = false
      });
      // List 是它的子类
      IEnumerable<AppraisalBases_xy> AppraisalBases02 = AppraisalBases_xy.ListAll();
      // AddRange添加范围:添加整个 ListAll 集合
      // 显示接受的是 IEnumerable 集合,但是也可以直接接受 List 集合,是因为 里氏替换原则:面向对象的基本原则之一【父类可以接受子类】
      AppraisalBases.AddRange(AppraisalBases02);

      /* AppraisalBases = AppraisalBases_xy.ListAll();
      // 向集合中角标为 0 的地方插入一条数据
      AppraisalBases.Insert(0, new AppraisalBases_xy
      {
        Id = 0,
        BaseType = "-查询所有-",
        AppraisalBase = "0",
        IsDel = "false"
      }); */

      // 获取数据源,为 List 里面的数据【是一些很恶心的东西,需要下面显示正确的】
      comboBox1.DataSource = AppraisalBases;
      // 显示的正常的数据
      comboBox1.DisplayMember = "BaseType";
      // 数据表里面的数据有关联的
      comboBox1.ValueMember = "id";
      // 不建议使用下面的方法给 comboBox1 添加数据
      //comboBox1.Text = "-查询所有-";
      //comboBox1.Items.Add("-查询所有-");
      //foreach (var appraisalBases in AppraisalBases)
      //{
      //  comboBox1.Items.Add(appraisalBases.BaseType);
      //}
    }

    private void button1_Click(object sender, EventArgs e)
    {
      BindDgv();
    }

    private void dataGridView1_MouseDown(object sender, MouseEventArgs e)
    {
      // 鼠标点击控件所有区域
      // 如果鼠标是右键点击
      if(e.Button == MouseButtons.Right)
      {
        tsmAdd.Visible = true;
        tsmEdit.Visible = false;
        tsmStart.Visible = false;
        tsmStop.Visible = false;
      }
    }

    private void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
    {
      // 鼠标点击控件单元格区域
      // dataGridView1.SelectionMode = RowHeaderSelect【默认为选中某个单元格】,改成 FullRowSelect【选中一行】
      // dataGridView1.MultiSelect = True【默认:允许多行选择】,改成 false【禁止多行选择】
      if (e.Button == MouseButtons.Right)
      {
        // 如果选中了某行
        if (e.RowIndex > -1)
        {
          // 鼠标右键选中当前行
          dataGridView1.Rows[e.RowIndex].Selected = true;
          tsmAdd.Visible = true;
          tsmEdit.Visible = true;
          // 选择的行的下标为0的行,下面的属性名为 IsDel 的值
          bool isDel = (bool)dataGridView1.SelectedRows[0].Cells["IsDel"].Value;
          // 如果选择行的 IsDel 为True【表示为已停职】
          if (isDel)
          {
            tsmStart.Visible = true;
          }
          else
          {
            tsmStop.Visible = true;
          }
        }
      }
    }

    private void tsmAdd_Click(object sender, EventArgs e)
    {
      FrmSetUser FrmSetUser01 = new FrmSetUser();
      FrmSetUser01.ShowDialog();
    }
  }
}

在这里插入图片描述


右键弹出选项,选择新建会弹出一个选项框,这里又需要新建一个窗体:

控件:groupBox2、label3、textBox、comboBox*2、checkBox、button

  • 设置属性可以参考前面的,都差不多的

具体代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WindowsFormsApp_xiaoyin01.Models;

namespace WindowsFormsApp_xiaoyin01 {
  public partial class FrmSetUser : Form {
    public FrmSetUser()
    {
      InitializeComponent();
    }

    // FormBorderStyle: FixedToolWindow; 设置窗体样式
    private void FrmSetUser_Load(object sender, EventArgs e)
    {
      List<AppraisalBases_xy> AppraisalBases = new List<AppraisalBases_xy>();
      AppraisalBases = AppraisalBases_xy.ListAll();
      comboBox1.DataSource = AppraisalBases;
      // 显示的正常的数据
      comboBox1.DisplayMember = "BaseType";
      // 数据表里面的数据有关联的
      comboBox1.ValueMember = "id";
    }

  }
}

在这里插入图片描述


三、前面忘了还有Models文件夹下面的两个文件

  • AppraisalBases_xy.cs 文件:
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WindowsFormsApp_xiaoyin01.Utility;

namespace WindowsFormsApp_xiaoyin01.Models {
  class AppraisalBases_xy {
    public int Id { get; set; }
    public string BaseType { get; set; }
    public int AppraisalBase { get; set; }
    public bool IsDel { get; set; }

    public static List<AppraisalBases_xy> ListAll()
    {
      List<AppraisalBases_xy> AppraisalBases = new List<AppraisalBases_xy>();
      DataTable dt = SqlHelper.ExecuteTable("SELECT * FROM s01_AppraisalBases");
      foreach (DataRow dRow in dt.Rows)
      {
        AppraisalBases.Add(ToModel(dRow));
      }
      return AppraisalBases;
    }

    // 把数据库里面的对象,转换成实体对象
    private static AppraisalBases_xy ToModel(DataRow dr)
    {
      AppraisalBases_xy AppraisalBases = new AppraisalBases_xy();
      AppraisalBases.Id = (int)dr["id"];
      AppraisalBases.BaseType = dr["BaseType"].ToString();
      AppraisalBases.AppraisalBase = (int)dr["AppraisalBase"];
      AppraisalBases.IsDel = (bool)dr["IsDel"];
      return AppraisalBases;
    }

  }
}
  • UserAppraisalBases.cs 文件:
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WindowsFormsApp_xiaoyin01.Utility;

namespace WindowsFormsApp_xiaoyin01.Models {
  public class UserAppraisalBases {
    public int Id { get; set; }
    public string UserName { get; set; }
    public string Sex { get; set; }
    public int BaseTypeld { get; set; }
    public string BaseType { get; set; }
    public int AppraisalBase { get; set; }
    public bool IsDel { get; set; }

    public static List<UserAppraisalBases> GetListJoinAppraisal()
    {
      List<UserAppraisalBases> UserAppraisalBases02 = new List<UserAppraisalBases>();
      DataTable dt = SqlHelper.ExecuteTable("SELECT a.id,a.UserName,a.sex,b.BaseType,a.BaseTypeld,b.AppraisalBase,a.isDel FROM s01_Users AS a LEFT JOIN s01_AppraisalBases AS b ON a.BaseTypeld=b.id");
      foreach (DataRow dr02 in dt.Rows)
      {
        UserAppraisalBases02.Add(ToMode(dr02));
      }
      return UserAppraisalBases02;
    }

    private static UserAppraisalBases ToMode(DataRow dr)
    {
      UserAppraisalBases UserAppraisalBases01 = new UserAppraisalBases();
      UserAppraisalBases01.Id = (int)dr["Id"];
      UserAppraisalBases01.UserName = dr["UserName"].ToString();
      UserAppraisalBases01.Sex = dr["Sex"].ToString();
      UserAppraisalBases01.BaseTypeld = (int)dr["BaseTypeld"];
      UserAppraisalBases01.BaseType = dr["BaseType"].ToString();
      UserAppraisalBases01.AppraisalBase = (int)dr["AppraisalBase"];
      UserAppraisalBases01.IsDel = (bool)dr["IsDel"];
      return UserAppraisalBases01;
    }

  }
}

待修改完善,后续已发
C# .net Framework Windows窗体应用【02】

笔记源码


一点点笔记,以便以后翻阅。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐