C#项目绩效考核实战提升(二)

7.数据的筛选

功能:通过筛选框在datagridview筛选出符合条件的用户

1.修改FrmUserManager.cs代码

(这里插入一下封装函数的快捷键,选择代码之后点左边的小锤子)
在这里插入图片描述

        private void BindDgv()
        {
            // 实现筛选功能
            string userName = txtUserName.Text.Trim();
            int baseTypeId = (int)cbxBase.SelectedValue;
            bool isStop = chkIsStop.Checked;
            dgvUserAppraisal.AutoGenerateColumns = false;
            // 当筛选框BaseType选择查询所有时,Id=0,但数据表中没有BaseTypeId = 0的值
            if (baseTypeId == 0)
            {
                dgvUserAppraisal.DataSource = UserAppraisalBases.GetListJoinAppraisal().FindAll
                    (m => m.UserName.Contains(userName) && m.IsDel == isStop);
            }
            else
            {
                // =>拉姆达表达式,Contains相当于数据库中的like
                dgvUserAppraisal.DataSource = UserAppraisalBases.GetListJoinAppraisal().FindAll
                    (m => m.UserName.Contains(userName) && m.BaseTypeId == baseTypeId && m.IsDel == isStop);
            }
        }

知识点:Lambda表达式
也是一种委托,委托参数类型。
lambda运算符"=>"的左边列出了需要的参数,右边定义了赋予lambda变量的方法的实现代码。
如果在lambda表达式的实现代码中需要多条语句,多条语句外必须添加花括号和return语句。
通过lambda表达式可以访问lambda表达式块外部的变量,这称为闭包。如果给多个线程使用闭包,了能遇到并发冲突。lambda表达书可以用于类型为委托的任意地方。

2.在按钮点击事件中绑定1的函数

双击搜索按钮

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

8.观察者模式与事件触发

观察者模式:
AfterSelect是一个方法,通过FrmMain.designer.cs获取到this.trvMenu.AfterSelect,点击此事件跳转,发现此AfterSelect是一个TreeViewEventHandler的事件,点击TreeViewEventHandler,发现TreeViewEventHandler是一个委托,通过委托生成事件,通过事件监听treeview控件有没有点击,这种设计模式称为观察者模式

给窗口左侧treeview添加一个事件AfterSelect
		private void trvMenu_AfterSelect(object sender, TreeViewEventArgs e)
        {
            // 第一个参数object sender是treeview本身,第二个参数e是treeview事件
            // 三个方法获取当前选中得node
            //bool b1 = ((TreeView)sender).SelectedNode == trvMenu.SelectedNode;
            //bool b2 = ((TreeView)sender).SelectedNode == e.Node;

            // 清除之前存在的背景色和前景色,如果不清除的话,选中第二个菜单,第一个菜单仍为蓝色
            foreach (TreeNode node in trvMenu.Nodes)
            {
                node.BackColor = Color.White;
                node.ForeColor = Color.Black;
            }
            e.Node.BackColor = SystemColors.Highlight;
            e.Node.ForeColor = Color.White;

        }

9.DataGridView选中行与右键菜单

功能:在用户上点击右键显示菜单:添加编辑和停用,在已停职的用户上点击右键显示菜单:添加编辑和启用,在空白处点击右键显示菜单:添加

1.拖动一个控件ContextMenuStrip
2.先将datagridview的属性ContextMenuStrip修改值选择刚才新建的控件
3.修改datagridview的事件MouseDown
		private void dgvUserAppraisal_MouseDown(object sender, MouseEventArgs e)
        {
            // 判断是否是右键单击
            if (e.Button == MouseButtons.Right)
            {
                tsmAdd.Visible = true;
                tsmEdit.Visible = false;
                tsmStart.Visible = false;
                tsmStop.Visible = false;
            }
        }
4.修改datagridview的事件CellMouseDown
  • 需要鼠标在选中的时候选中一整行,所以将datagrifview的属性SelectionMode属性值修改为FullRowSelect
  • 只需要选中一行,不需要选中多行,所以将MultiSelect的值修改为false
  • 右键才出现添加编辑等的功能,点击datagridview右上角中的小三角,取消选中启用添加,编辑,删除,这样在鼠标左键点击时就不对表格进行修改
        private void dgvUserAppraisal_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
        {
            if(e.Button == MouseButtons.Right)
            {
                // 如果e.RowIndex = -1,表示没有选中任何行
                if (e.RowIndex > -1)
                {
                    // 鼠标在某行点击右键,表示这行被选中
                    dgvUserAppraisal.Rows[e.RowIndex].Selected = true;
                    tsmAdd.Visible = true;
                    tsmEdit.Visible = true;
                    tsmStart.Visible = false;
                    tsmStop.Visible = false;
                }
            }
        }

10.DataGridView单行处理及项目分层

功能:判断在用户上点击右键显示的菜单显示停用还是启用。

1.将表格是否停用这一行的显示形式改成复选框

点击datagridview右上角小三角,编辑列,IsDel属性值ColumnType修改成DataGridViewCheckBoxColumn

2.修改FrmUserManager.cs代码
// 判断右键菜单应该显示启用还是停用
bool isDel = (bool)dgvUserAppraisal.SelectedRows[0].Cells["IsDel"].Value;
if(isDel)
{
   tsmStart.Visible = true;
}
else
{
    tsmStop.Visible = true;
}

功能:添加用户

3.新建一个窗体FrmSetUser.cs

在这里插入图片描述

  1. 修改窗体属性值FormBorderStyle为FixedToolWindow
  2. 按照需求修改窗体样式
  3. 给身份下拉框获取数据库中的身份类型
List<AppraisalBases> appraisalBases = new List<AppraisalBases>();
appraisalBases = AppraisalBases.ListAll();
// 单向数据源绑定
cbxBase.DataSource = appraisalBases;
cbxBase.DisplayMember = "BaseType";
cbxBase.ValueMember = "Id";
  1. 双击ContextMenuStrip中的添加按钮,把FrmSetUser.cs显示出来
private void tsmAdd_Click(object sender, EventArgs e)
{
   FrmSetUser frmSetUser = new FrmSetUser();
   frmSetUser.ShowDialog();
}

功能:拆分项目

4.新建一个项目(类库),将/Models文件夹下的两个类移动到新建的Appraisal_Systerm.Models
5.在原有的项目添加引用Appraisal_Systerm.Models

操作步骤:在引用上右键,添加引用

6.同理,提取出Appraisal_Systerm.Utility

C#项目分层的三层架构:
DAL:数据访问层
BLL:业务逻辑层
UI:视图层

11.反射遍历获取的数据并转换成实体

1.在Models项目中新建一个Users.cs类

功能:通过反射获取Users表中的数据

using Appraisal_Systerm.Utility;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Appraisal_Systerm.Models
{
    public class Users
    {
        // 属性与数据表Users列的内容一致
        public int Id { get; set; }
        public string UserName { get; set; }
        public string Sex { get; set; }
        public string Password { get; set; }
        public int BaseTypeId { get; set; }
        public bool IsDel { get; set; }

        public static List<Users> ListAll()
        {
            DataTable dt = SqlHelper.ExecuteTable("SELECT u.Id,u.Password,u.BaseTypeId,u.UserName,u.Sex,u.IsDel FROM Users u");
            List<Users> users = new List<Users>();
            foreach (DataRow dr in dt.Rows)
            {
                users.Add(dr.DataRowToModel<Users>());
            }
            return users;
        }
}

2.在Utility项目中新建一个ToModel.cs类
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Appraisal_Systerm.Utility
{
    public static class ToModel
    {
        // 扩展方法
        public static TModel DataRowToModel<TModel>(this DataRow dr)
        {
            // 反射:类被封装到一个盒子里,没有办法获取到类,想要获取到类的属性和方法的行为叫反射。
            // 泛型反射:想要获取到所有类型类的方法,如果用object就要涉及到拆箱和封箱效率低,所以用泛型。
            // this:扩展方法,扩展方法必须在静态类中,扩展方法也必须是一个静态方法。

            // 获取泛型方法的类型
            Type type = typeof(TModel);
            // 获取TModel实例化对象
            TModel md = (TModel)Activator.CreateInstance(type);
            foreach (var prop in type.GetProperties())
            {
                prop.SetValue(md,dr[prop.Name]);
            }
            return md;
        }
    }
}

反射用的是System.Type类
存储类型的引用:Type t = typeof(double);运算符的参数是类型的名称。
type.GetProperties():用于获取对应数据类型的成员信息。

12.方法扩展及参数化改造

1.为了实现Sql参数化,修改SqlHelper.cs

在这里插入图片描述

2.修改Users.cs代码
        // 添加
        public static int Insert(Users user)
        {
            // 采用Sql注入,方法是Sql语句参数化
            return SqlHelper.ExecuteNonQuery($"INSERT INTO Users(UserName,Password,Sex,BaseTypeId,IsDel) VALUES(@UserName,@Password,@Sex,@BaseTypeId,@IsDel)",
                new SqlParameter("@UserName",user.UserName),
                new SqlParameter("@Password", user.Password),
                new SqlParameter("@Sex", user.Sex),
                new SqlParameter("@BaseTypeId", user.BaseTypeId),
                new SqlParameter("@IsDel", user.IsDel)
                );
        }

        // 修改
        public static int Update(Users user)
        {
            // 采用Sql注入,方法是Sql语句参数化
            int rows =  SqlHelper.ExecuteNonQuery($"UPDATE Users SET UserName=@UserName,Password=@Password,Sex=@Sex,BaseTypeId=@BaseTypeId,IsDel=@IsDel WHERE Id=@Id",
                new SqlParameter("@Id", user.Id),
                new SqlParameter("@UserName", user.UserName),
                new SqlParameter("@Password", user.Password),
                new SqlParameter("@Sex", user.Sex),
                new SqlParameter("@BaseTypeId", user.BaseTypeId),
                new SqlParameter("@IsDel", user.IsDel)
                );
            return rows;
        }

13.用户添加及联动刷新

1.用户添加功能,双击保存按钮跳转到方法
        private void btnSave_Click(object sender, EventArgs e)
        {
            string userName = txtUserName.Text.Trim();
            int baseTypeId = (int)cbxBase.SelectedValue;
            string sex = cbxSex.Text;
            bool isDel = chkIsStop.Checked;
            Users user = new Users
            {
                UserName = userName,
                BaseTypeId = baseTypeId,
                Password = "111",
                IsDel = isDel,
                Sex = sex
            };
            Users.Insert(user);
            MessageBox.Show("用户添加成功!");
            this.Close();
        }
2.联动刷新,为了让窗体实现添加完一个用户之后窗体关闭且列表刷新
  1. 首先在btnSave_Click最后加入 MessageBox.Show("用户添加成功!"); this.Close();
  2. 在FrmUserManager.cs中加入BindDgv()函数,刷新列表
    (模式窗体的特性:当窗体对象调用ShowDialog中,代码卡住不往下执行,关闭模式窗体之后,继续往下执行代码)在这里插入图片描述

14.数据库还原

15.委托的使用与数据的新增响应

功能:点击添加之后datagridview列表自动刷新。
插入一个神奇的快捷键,在VS Code里面填写!+回车,则搭出html框架
委托:
把方法赋值给一个变量,并将这个变量作为一个参数,传递到另一个方法里面去(用js语言举例是因为js是一个弱类型语言,可以把方法赋值给变量)

1.在FrmUserManager.cs中创建一个接受方法的关键字
public delegate void DelBindDgv();// 我们自己声明一个类似string/int关键字
2.声明一个委托变量
DelBindDgv delBindDgv;
3.把方法赋值给委托变量
delBindDgv = BindDgv;
4.在FrmSetUser.cs中重复以上步骤

如果类型为private,则一般命名前方加一个小写的_

private DelBindDgv _delBindDgv;
public FrmSetUser(DelBindDgv delBindDgv)
{
   InitializeComponent();
   _delBindDgv = delBindDgv;
}

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值