C#winform制作学生列表

学生列表

记录学习制作学生列表的过程。

准备数据源

​ 建一个实体类,设置数据源的类型。可以新建一个文件夹Model,在它下面建一个Student.cs实体类。

Student.cs


namespace _1.窗体.Model
{
    // 实体类:实体本质对现实的描述,映射ORM(Object Relation Mapping)
    // POCO
    public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
        public bool Sex { get; set;}
        public DateTime Birthday { get; set; }
        public string Description { get; set; }
    }
}

​ 新建一个文件夹Data存放数据源,创建StudentData.cs类包含数据信息。

StudentData.cs


namespace _1.窗体.Data
{
    public static class StudentData
    {
        // 1。数据源,数据的源类型已经准备 Student
        public static List<Student> Students = new List<Student>() {
            new Student(){ Id=1,Name="张三",Age=20,Sex=true,Birthday=new DateTime(2000,1,1),Description="个人描述"},
            new Student(){ Id=2,Name="李四",Age=21,Sex=false,Birthday=new DateTime(2000,1,1),Description="个人描述"},
        };
    }
}

学生信息窗体

StudentForm.cs

​ 先拖入控件,这里需要用到Lable(标签),TextBox(文本框),ComboBox(下拉框,用于选择性别等信息),DateTimePicker(日期时间选择器),Button(按钮),DataGridView(数据网格视图)。给相应的控件更改Text,Name,其中Name按小驼峰的风格去改,dtpBirthday,方便在写代码的时候认出来。


	//窗体加载时的设置,窗体的Load事件构造函数执行
	private void StudentForm_Load(object sender, EventArgs e)
{
    // 性别默认选中“全部”
    cbbSex.SelectedIndex = 0;
    // 生日默认为空
    dtpBirthdayStart.CustomFormat = " ";
    dtpBirthdayEnd.CustomFormat = " ";
    // 绑定数据源
    BindDataGridView();
}


// 把数据源students和datagridview控件绑定一起。
private void BindDataGridView()
{
    List<Student> filter = StudentData.Students;//绑定数据源给filter列表,等到按条件查询之后,会赋值给dataGridView的DataSource,实现数据网格绑定数据源。
    
    //查询名字
//如果输入的名字匹配,则返回名字对应的学生信息,返回的类型是一个列表,并将结果存储在 filter 中。
    if (!string.IsNullOrWhiteSpace(txtName.Text))
        //筛选txtName.Text 不为空且不为仅包含空白字符的字符串。sNullOrEmpty仅检查空和null,而IsNullOrWhiteSpace还会考虑字符串中只包含空格的情况。
        filter = filter.FindAll(stu1 => stu1.Name.Contains(txtName.Text));
        //定义筛选的条件。Find() 获取第一个符合条件的元素并返回该元素,FindAll() 获取所有符合条件的元素,并最终返回一个列表。
    
    //查询匹配的性别
    if (cbbSex.SelectedIndex == 1) // 男
        filter = filter.FindAll(stu => stu.Sex == false);

    if (cbbSex.SelectedIndex == 2) // 女
        filter = filter.FindAll(stu => stu.Sex);

    //匹配生日信息,这样写可以看起来麻烦,但是有用。这样可以限定那个日期在规定的时间内。先转换为字符串,再转换成DataTime,大于start的stu对象以列表的形式赋给filter。
    if (!string.IsNullOrWhiteSpace(dtpBirthdayStart.Text))
    {
        string date1 = DateTime.Parse(dtpBirthdayStart.Text).ToString("yyyy-MM-dd");
        DateTime start = DateTime.Parse($"{date1} 00:00:00");
        filter = filter.FindAll(stu => stu.Birthday >= start);
    }

    if (!string.IsNullOrWhiteSpace(dtpBirthdayEnd.Text))
    {
        string date1 = DateTime.Parse(dtpBirthdayEnd.Text).ToString("yyyy-MM-dd");
        DateTime end = DateTime.Parse($"{date1} 23:59:59");
        filter = filter.FindAll(stu => stu.Birthday <= end);
    }
    

    //改变行的高度,要求在绑定数据源之前设置行高才有效。(数据行)
    dataGridView1.RowTemplate.Height = 30;

    //先把上次绑定的数据源清除,再重新绑定,这样可以解决列表中数据已变化,但网格没有刷新的问题。数据网格的DataSource属性比较特殊,修改数据,数据源里面的变化不会自动更新。需要清理Clear()之后,再更新。
    dataGridView1.DataSource = null;
    dataGridView1.DataSource = filter.ToList();

    //列宽平分
    dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
    //改变标题的高度;
    dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing;
    dataGridView1.ColumnHeadersHeight = 30;
    //改变行头宽度
    dataGridView1.RowHeadersWidth = 30;
    dataGridView1.RowHeadersVisible = true;
    //改变背景
    dataGridView1.BackgroundColor = Color.White;
    // 更改列标题,获取列有两种方式:列名,列索引
    //dataGridView1.Columns[0].HeaderText = "学生编号";
    dataGridView1.Columns["Name"].HeaderText = "学生姓名";
    dataGridView1.Columns["Age"].HeaderText = "年龄";
    dataGridView1.Columns["Sex"].HeaderText = "性别";
    dataGridView1.Columns["Birthday"].HeaderText = "出生日期";
    dataGridView1.Columns["Description"].HeaderText = "个人描述";
    // 格式化日期列   Default默认,Cell单元格
    dataGridView1.Columns["Birthday"].DefaultCellStyle.Format = "yyyy-MM-dd HH:mm:ss";
    dataGridView1.Columns["Id"].DefaultCellStyle.Format = "D2";
    dataGridView1.Columns["Age"].DefaultCellStyle.Format = "0岁";

    // 设置列的宽,Columns列,Rows行
    dataGridView1.Columns["Id"].Width = 60;
    // 设置列的显示或隐藏(可见性)
    //dataGridView1.Columns[0].Visible = false;

}


    // 查询按钮逻辑
    private void btnSearch_Click(object sender, EventArgs e)
    {
        BindDataGridView(); // 点击查询时,调用此方法,绑定数据源
    }

    
	// 生日查询条件变化时,重新设置格式化,防止不能选择日期。
    private void dtpBirthdayStart_ValueChanged(object sender, EventArgs e)
    {
        dtpBirthdayStart.CustomFormat = "yyyy-MM-dd";
    }

    private void dtpBirthdayEnd_ValueChanged(object sender, EventArgs e)
    {
        dtpBirthdayEnd.CustomFormat = "yyyy-MM-dd";
    }

     //添加一个学生
     private void btnAdd_Click(object sender, EventArgs e)
    {
        AddStudentForm form = new AddStudentForm();
        // 窗体对话框会返回一个结果,是个枚举值,常用的结果:OK,Cancel
        // AddStudentForm窗体返回的结果。
        DialogResult dialogResult = form.ShowDialog();
        if (dialogResult == DialogResult.OK)
        {
            BindDataGridView();// 重新绑定数据源
        }
    }
    

   private void btnClearBirthday_Click(object sender, EventArgs e)
  {
      // 清空生日选中的值,以便下次继续选择其他日期
      dtpBirthdayStart.CustomFormat = " ";
      dtpBirthdayEnd.CustomFormat = " ";
  }
  

// 删除按钮逻辑
private void btnDelete_Click(object sender, EventArgs e)
{
    if (dataGridView1.SelectedRows.Count == 0)
    {
        MessageBox.Show("请选择删除的行!", "提示框", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return;
    }

    if (dataGridView1.SelectedRows.Count > 1)
    {
        MessageBox.Show("一次只能删除一个!", "提示框", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return;
    }

    int id = (int)dataGridView1.SelectedRows[0].Cells["Id"].Value;

    DialogResult dialogResult = MessageBox.Show($"你确定要删除Id={id}这条数据吗?", "询问", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
    if (dialogResult == DialogResult.Yes)
    {
        //Student student = StudentData.Students.Find(stu => stu.Id == id);
        //StudentData.Students.Remove(student);如果没有找到匹配的对象,Find 方法会返回 null ,此时直接调用 Remove 可能会导致运行时错误。
        int index = StudentData.Students.FindIndex(stu => stu.Id == id);
        StudentData.Students.RemoveAt(index);
        BindDataGridView();
    }
}


// 修改按钮逻辑
private void btnUpdate_Click(object sender, EventArgs e)
{
    // SelectedRows选中行
    if (dataGridView1.SelectedRows.Count == 0)
    {
        MessageBox.Show("请选择修改的行!", "提示框", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return;
    }

    if (dataGridView1.SelectedRows.Count > 1)
    {
        MessageBox.Show("一次只能修改一个!", "提示框", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return;
    }

    // 拿到一行中主键(唯一),拿到学生Id   Cells["Id"].Value拿到某个单元格的值,值有装箱操作,使用时拆箱。
    int id = (int)dataGridView1.SelectedRows[0].Cells["Id"].Value;

    EditStudentForm editStudentForm = new EditStudentForm(id);
    DialogResult dialogResult = editStudentForm.ShowDialog();
    if (dialogResult == DialogResult.OK)
    {
        BindDataGridView();// 重新绑定数据源
    }
}

//修改性别和年龄的显示样式,性别修改不成功。
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
 {
     //if (e.RowIndex != -1 && e.ColumnIndex == 3)  // 性别
     if (this.dataGridView1.Columns[e.ColumnIndex].Name == "Sex")
     {
         bool sex = e.Value.ToString() == "True";
         Debug.WriteLine(sex ? "女" : "男");
		//e.Value = sex ? "女" : "男";在列表中是一个复选框的样式,不能修改成字符串。
     }

     if (this.dataGridView1.Columns[e.ColumnIndex].Name == "Age")
     {
         e.CellStyle.ForeColor = Color.Green;
         e.Value = e.Value.ToString() + "岁";
     }	
 }

添加学生窗体

AddStudentForm.cs


private void AddStudentForm_Load(object sender, EventArgs e)
{
    // 练习集合
    //cbbSex.Items.Add("hello");
    cbbSex.Items.Insert(0, "请选择...");
    // 默认选中的索引
    cbbSex.SelectedIndex = 0;
}

private void btnSave_Click(object sender, EventArgs e)
{
    //1.校验数据  永远不要相信用户输入
    #region 数据校验
    if (string.IsNullOrWhiteSpace(txtName.Text))
    {
        MessageBox.Show("请输入学生姓名!", "提示框", MessageBoxButtons.OK, MessageBoxIcon.Information);
        txtName.Focus(); // 让学生姓名输入框获取焦点
        return;
    }

    if (!(nudAge.Value >= 18 && nudAge.Value <= 65))
    {
        MessageBox.Show("年龄要求在[18-65]岁之间!", "提示框", MessageBoxButtons.OK, MessageBoxIcon.Information);
        nudAge.Focus();
        return;
    }

    if (cbbSex.SelectedIndex == 0)
    {
        MessageBox.Show("请选择性别!", "提示框", MessageBoxButtons.OK, MessageBoxIcon.Information);
        return;
    }

    if (string.IsNullOrWhiteSpace(dtpBirthday.Text))
    {
        MessageBox.Show("请选择生日!", "提示框", MessageBoxButtons.OK, MessageBoxIcon.Information);
        return;
    }
    else
    {
        int year1 = DateTime.Now.Year;
        int year2 = dtpBirthday.Value.Year;
        int age = int.Parse(nudAge.Value.ToString());
        if (year1 - year2 != age)
        {
            MessageBox.Show("生日和年龄不匹配!", "提示框", MessageBoxButtons.OK, MessageBoxIcon.Information);
            return;
        }
    }

    if (string.IsNullOrWhiteSpace(rtbDescription.Text))
    {
        MessageBox.Show("请填写个人描述!", "提示框", MessageBoxButtons.OK, MessageBoxIcon.Information);
        return;
    }
    #endregion

    int count = StudentData.Students.Count; // 拿列表项的数量(长度)
    int maxIndex = count - 1;  // 最后一个项的索引(最大索引)
    Student lastStudent = StudentData.Students[maxIndex]; // 拿到列表中最后一个学生
    int maxId = lastStudent.Id;

    Student oneStudent = new Student()
    {
        Id = maxId + 1,
        Name = txtName.Text,
        Age = int.Parse(nudAge.Value.ToString()),
        Sex = cbbSex.SelectedText == "男" ? false : true,
        Birthday = dtpBirthday.Value,
        Description = rtbDescription.Text,
    };
    StudentData.Students.Add(oneStudent);

    // 给另外一个窗体返回结果。默认行为:当前窗体会关闭
    DialogResult = DialogResult.OK;
}

修改学生窗体

EditStudentForm.cs


public partial class EditStudentForm : Form
 {
     // 存储要编辑学生的Id,拿到Id目的为了拿学生实体(模型)
     private int editId = 0;
     public EditStudentForm(int id)
     {
         InitializeComponent();
         editId = id;
     }

     // 窗体加载后,先把编辑学生原来信息显示到界面
     private void EditStudentForm_Load(object sender, EventArgs e)
     {
         if (editId != 0)
         {
             //Student editStudent = StudentData.Students.Find(stu => stu.Id == editId);
             Student editStudent = StudentData.Students.Where(stu => stu.Id == editId).ToList()[0];
             // 把学生实体相应的属性赋值给相应的控件。注意细节:类型
             txtName.Text = editStudent.Name;
             nudAge.Value = editStudent.Age;
             rbBoy.Checked = editStudent.Sex == false;
             rbGril.Checked = editStudent.Sex == true;
             dtpBirthday.Value = editStudent.Birthday;  // dtpBirthday.Text
             //dtpBirthday.Text = editStudent.Birthday.ToString("yyyy-MM-dd");
             rtbDescription.Text = editStudent.Description;
         }
     }

     private void btnSave_Click(object sender, EventArgs e)
     {
         // 校验省略
         #region 数据校验
         if (string.IsNullOrWhiteSpace(txtName.Text))
         {
             MessageBox.Show("请输入学生姓名!", "提示框", MessageBoxButtons.OK, MessageBoxIcon.Information);
             txtName.Focus(); // 让学生姓名输入框获取焦点
             return;
         }

         if (!(nudAge.Value >= 18 && nudAge.Value <= 65))
         {
             MessageBox.Show("年龄要求在[18-65]岁之间!", "提示框", MessageBoxButtons.OK, MessageBoxIcon.Information);
             nudAge.Focus();
             return;
         }

         if (string.IsNullOrWhiteSpace(dtpBirthday.Text))
         {
             MessageBox.Show("请选择生日!", "提示框", MessageBoxButtons.OK, MessageBoxIcon.Information);
             return;
         }
         else
         {
             int year1 = DateTime.Now.Year;
             int year2 = dtpBirthday.Value.Year;
             int age = int.Parse(nudAge.Value.ToString());
             if (year1 - year2 != age)
             {
                 MessageBox.Show("生日和年龄不匹配!", "提示框", MessageBoxButtons.OK, MessageBoxIcon.Information);
                 return;
             }
         }

         if (string.IsNullOrWhiteSpace(rtbDescription.Text))
         {
             MessageBox.Show("请填写个人描述!", "提示框", MessageBoxButtons.OK, MessageBoxIcon.Information);
             return;
         }
         #endregion

         // 编辑学生(修改)
         // 拿到编辑学生的索引
         int index = StudentData.Students.FindIndex(stu=>stu.Id == editId);

         // 产生一个新学生,注意:新学生和原来的学生有一个地方不变:编号Id
         Student newStudent = new Student() { 
             Id = editId,
             Name = txtName.Text,
             Age = int.Parse(nudAge.Value.ToString()),
             Sex = rbGril.Checked,
             Birthday = dtpBirthday.Value,
             Description = rtbDescription.Text,
         };
         StudentData.Students[index] = newStudent;

         DialogResult = DialogResult.OK;
     }
 }
 
posted @ 2024-08-16 21:12  海域  阅读(47)  评论(0编辑  收藏  举报