第六章:DataGridView控件及数据绑定

本章目标

  1. 使用DataSet存放数据
  2. 使用ComboBox进行数据绑定
  3. 使用DataGridView进行数据绑定
  4. 使用DataSet实现数据更新

本章内容

DataSet数据集(课程回顾)

  1. ADO.NET两大组成部分

    1715044622979

  2. 通过DataSet数据集获取数据库数据 ,代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    DataSet ds = new DataSet();//创建数据集

    string connString = "server=.;database=MySchool;uid=sa;pwd=sa;";
    using (SqlConnection conn = new SqlConnection(connString))
    {
    string sql = "select gradeId,gradeName from Grade";
    SqlDataAdapter sda = new SqlDataAdapter(sql, conn);
    sda.Fill(ds,"Grade");//填充表格

    foreach (DataRow dataRow in ds.Tables["Grade"].Rows)
    {
    Console.WriteLine(dataRow["GradeId"] + "\t" + dataRow["GradeName"]);
    }
    }

ComboBox控件(绑定数据列表)

  1. ComboBox数据绑定3个属性

    1. DataSource:数据源
    2. ValueMember:实际值
    3. DisplayMember:显示的值
  2. 绑定ComboBox数据源

    1
    2
    3
    this.cboGrade.DataSource = ds.Tables["Grade"];
    this.cboGrade.ValueMember = "GradeId";//绑定值的属性
    this.cboGrade.DisplayMember = "GradeName";//绑定显示的文本属性
  3. 如何在查询出来的数据中显示”请选择“:

    1
    2
    3
    4
    5
    6
    7
    8
    // 向年级表的第1行添加数据“全部”
    DataRow row = ds.Tables["Grade"].NewRow();
    row[0] = -1;
    row[1] = "全部";
    ds.Tables["Grade"].Rows.InsertAt(row, 0);

    //重新绑定数据源
    .....

DataGridView控件(数据视图)

  1. 为什么要使用DataGridView?

    问题:当我们从数据库把数据加载到数据集中时,如何将数据集的数据更加容易展示到窗体中呢?

    DataGridView可以做到,如下图:

    1716369997268

  2. DataGridView 的重要属性:

    属性名称 说 明
    Columns 包含的列的集合
    DataSource DataGridView 的数据源
    ReadOnly 是否可以编辑单元格
    AllowUserToAddRows 设置为True时,会在最后一行自动添加一行空行,用于新增数据
    AllowUserToDeleteRows 设置为True时,会允许用户删除表格中选中的行
    AllowUserToOrderColumns 设置为True时,会允许用户通过拖拽表格列标题来重新排序表格列
    AllowUserToResizeColumns 设置为True时,会允许用户通过拖拽表格列标题来调整表格列宽度
    AllowUserToResizeRows 设置为True时,会允许用户通过拖拽表格行边框来调整表格行高度
    AlternatingRowsDefaultCellStyle 奇数行和偶数行的样式
    MultiSelect 是否允许用户同时选择多个单元格、行或列。
    SelectionMode 设置单元格选择模式
    RowHeadersVisible 设置或获取一个值,指示是否显示行标题列
  3. 使用 DataGridView 显示数据

    1. 将DataGridView控制拖入窗体,取名为:dgvData,如下图:

      1716370266562

    2. 代码实现功能:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      private void FrmDataGridView_Load(object sender, EventArgs e)
      {
      DataSet ds = new DataSet();//创建数据集

      string connString = "server=.;database=MySchool;uid=sa;pwd=sa;";
      using (SqlConnection conn = new SqlConnection(connString))
      {
      string sql = "select gradeId,gradeName from Grade";
      SqlDataAdapter sda = new SqlDataAdapter(sql, conn);
      sda.Fill(ds, "Grade");//填充表格

      dgvData.DataSource = ds.Tables["Grade"];//绑定数据源
      }
      }
    3. 打开窗体,呈现效果如下:

      1716370396011

      1. 数据从DataSet中加载到窗体
      2. 但是列名为数据库的列名,如何显示中文的呢?
    4. 给DataGridView添加列,且绑定列名:

      1716370596445

      1716370680945

    5. 最终效果如下 :

      1716370732995

  4. DataGridView 中各列的主要属性

    1716371124411

    1. 常用属性:

      属性名称 说 明
      HeaderText 列标题文本
      Visible 指定列是否可见
      ReadOnly 指定单元格是否为只读
      DataPropertyName 绑定的数据列的名称
      ColumnType 列的类型

DataGridView常用属性

  1. AutoSizeColumnsMode、AutoSizeRowsMode:

    AutoSizeColumnsMode属性是用于设置DataGridView控件的列宽自适应模式,其枚举类型有:

    1. DataGridViewAutoSizeColumnsMode.None:表示不自适应;
    2. DataGridViewAutoSizeColumnsMode.AllCells:自适应所有单元格内容的宽度;
    3. DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader:自适应所有单元格内容的宽度,除了列标题;
    4. DataGridViewAutoSizeColumnsMode.ColumnHeader:适应列标题的宽度;
    5. DataGridViewAutoSizeColumnsMode.DisplayedCells:根据显示的单元格内容自适应单元格宽度;
    6. DataGridViewAutoSizeColumnsMode.DisplayedCellsExceptHeader:根据显示的单元格内容自适应单元格宽度,除了列标题。
    7. DataGridViewAutoSizeColumnsMode.Fill:DataGridView 的列宽会自动调整,以填满控件的可用空间,列宽将会平均分配

    AutoSizeRowsMode属性是用于设置DataGridView控件的行高自适应模式,其枚举类型有:

    1. DataGridViewAutoSizeRowsMode.None:表示不自适应;
    2. DataGridViewAutoSizeRowsMode.AllCells:自适应所有单元格内容的高度;
    3. DataGridViewAutoSizeRowsMode.DisplayedCells:根据显示的单元格内容自适应行高度。
  2. ColumnHeadersBorderStyle、ColumnHeadersDefaultCellStyle、ColumnHeadersHeightSizeMode、ColumnHeadersVisible、Columns
    DataGridView控件是Winform中常用的数据展示控件之一。下面是对其中几个常用属性的介绍:

    1. ColumnHeadersBorderStyle:用于设置列标题边框样式。可以设置为None、Single、Raised、Sunken等值。
    2. ColumnHeadersDefaultCellStyle:用于设置列标题单元格的默认样式。可以设置颜色、字体、对齐方式等属性。
    3. ColumnHeadersHeightSizeMode:用于设置列标题高度的大小模式。可以设置为AutoSize、DisableResizing、EnableResizing等值。
    4. ColumnHeadersVisible:用于控制列标题是否可见。可以设置为True或False。
    5. Columns:用于获取或设置DataGridView控件的列集合。可以通过该属性添加、删除、编辑列。
  3. ScrollBars:控制DataGridView控件的滚动条的显示方式,可以设置为None、Horizontal、Vertical、Both四种选择。

    • ScrollBars.None:不显示滚动条。
    • ScrollBars.Horizontal:只显示水平滚动条。
    • ScrollBars.Vertical:只显示垂直滚动条。
    • ScrollBars.Both:同时显示水平和垂直滚动条。

DataGridView常用功能

  1. 功能一:查询学生信息,性别要求是下拉列表,年级也是列表呈现,效果如下:

    1716448548910

  2. 当性别在DataGridView里是下拉列表,而且是固定值,则要先设置如下:

    1716448962512

  3. 那么年级是下拉列表,则是从数据库动态加载出来的数据怎么处理?

    1. 设置年级下拉列表的名称Name:clGrade

      1716449366034

    2. 绑定数据:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      public void LoadGrade()
      {
      using (SqlConnection conn = new SqlConnection(connString))
      {
      string sql = "select gradeId,gradeName from Grade";
      SqlDataAdapter sda = new SqlDataAdapter(sql, conn);
      sda.Fill(ds, "Grade");//填充表格

      clGrade.DataSource = ds.Tables["Grade"];
      clGrade.DisplayMember = "GradeName";
      clGrade.ValueMember = "GradeId";
      }
      }

      private void FrmStudentDataGridView_Load(object sender, EventArgs e)
      {
      LoadGrade();//先绑定年级数据源
      LoadData();
      }
  4. 实现查询,绑定属性:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    public void LoadData()
    {
    //清空原来数据
    if (ds.Tables["Student"]!=null)
    {
    ds.Tables["Student"].Clear();
    }

    using (SqlConnection conn = new SqlConnection(connString))
    {
    string sql = " SELECT StudentNo,StudentName,Sex,GradeId,Phone,Address FROM Student Where 1=1 ";
    if (!string.IsNullOrEmpty(txtName.Text.Trim()))
    {
    sql += " and StudentName like '%" + txtName.Text + "%'";
    }
    SqlDataAdapter sda = new SqlDataAdapter(sql, conn);
    sda.Fill(ds, "Student");//填充表格

    dgvData.DataSource = ds.Tables["Student"];//绑定数据源
    }
    }

    private void FrmStudentDataGridView_Load(object sender, EventArgs e)
    {
    LoadGrade();
    LoadData();
    }
    //查询功能
    private void btnSearch_Click(object sender, EventArgs e)
    {
    LoadData();
    }

    注意事项:

    一定要清空数据后再加载,不然会在累加数据

    最终效果:

    1716449963024

  5. 如何获取选中行的数据

    1
    2
    string studentNo = dgvData.CurrentRow.Cells[1].Value.ToString();//获取当前行指定列的数据
    string studentNo = dgvData.SelectedRows[0].Cells["clStudentNo"].Value.ToString();//获取选中行的第一行指定列(列名)的数据
  6. 如何实现全选功能,反选功能

    1716451406707

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    //全选
    private void btnGetStudentNo_Click(object sender, EventArgs e)
    {
    //循环行数据
    foreach (DataGridViewRow dgvr in dgvData.Rows)
    {
    dgvr.Cells[0].Value = true;//获取第一个单元格的值且设置为true,选中状态
    }
    }

    //反选
    private void button1_Click(object sender, EventArgs e)
    {
    //循环行数据
    foreach (DataGridViewRow dgvr in dgvData.Rows)
    {
    dgvr.Cells[0].Value = !Convert.ToBoolean(dgvr.Cells[0].Value);//获取第一个单元格的值且设置为true,选中状态
    }
    }
  7. 如何在DataGridView标题第一列加入全选复选框:

    1716515850769

    代码实现:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    private void FrmStudentDataGridView_Load(object sender, EventArgs e)
    {
    //1.创建CheckBox对象
    System.Windows.Forms.CheckBox ckBox = new System.Windows.Forms.CheckBox();
    ckBox.Text = "全选";
    ckBox.Checked = true;

    //2.获取DataGridView第一列的区域
    System.Drawing.Rectangle rect =dgvData.GetCellDisplayRectangle(0, -1, true);

    //3.设置复选框的大小和位置
    ckBox.Size = new System.Drawing.Size(dgvData.Columns[0].Width, 18);
    ckBox.Location = rect.Location;

    //4.给复选框添加事件
    ckBox.CheckedChanged += new EventHandler(Checkbox_CheckedChanged);

    //5.将复选框加入到DataGridView控件中
    dgvData.Controls.Add(ckBox);
    }

    //6.完成事件,功能代码省略.....
    private void Checkbox_CheckedChanged(object sender, EventArgs e)
    {
    throw new NotImplementedException();
    }

DataSet数据源更新(课程回顾)

  1. 问题:如何把修改过的学生信息保存到数据库中?

    使用 DataAdapter 的 Update() 方法

    1716516327847

  2. DataAdapter的Update()方法

    1. 作用:

      把数据集中修改过的数据提交到数据源

    2. 语法:

      1
      dataAdapter.Update(数据集对象, "数据表名称");

      相关说明:

      调用相应的命令执行:UpdateCommand、InsertCommand、DeleteCommand

  3. SqlCommandBuilder 对象

    1. 作用:利用 SqlCommandBuilder 对象能够自动生成

      INSERT 命令:InsertCommand

      UPDATE 命令:UpdateCommand

      DELETE 命令:DeleteCommand

    2. 语法:

      1
      2
      SqlCommandBuilder builder = 
      new SqlCommandBuilder(已创建的DataAdapter对象);

      注意事项:

      使用SqlCommandBuilder更新数据库只能用于单表操作,且查询语句中包含主键列

  4. 具体步骤:

    1. 自动生成用于更新的相关命令

      1
      2
      3
      SqlCommandBuilder builder = 
      new SqlCommandBuilder(已创建的DataAdapter对象);

    2. 将 DataSet 的数据提交到数据源

      1
      DataAdapter对象. Update(数据集对象, "数据表名称字符串");
    3. 示例:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      DataSet ds = new DataSet();
      SqlDataAdapter sda = null;
      string connString = "server=.;database=MySchool;uid=sa;pwd=sa;";

      public FrmGradeDataGridView()
      {
      InitializeComponent();
      }

      private void FrmGradeDataGridView_Load(object sender, EventArgs e)
      {

      string sql = " SELECT GradeId,GradeName FROM Grade Where 1=1 ";
      sda = new SqlDataAdapter(sql, connString);
      sda.Fill(ds, "Grade");//填充表格

      dataGridView1.DataSource = ds.Tables["Grade"];//绑定数据源
      }

      private void button1_Click(object sender, EventArgs e)//保存操作
      {
      SqlCommandBuilder sqlBuilder = new SqlCommandBuilder(sda);
      sda.Update(ds,"Grade");
      }

本章总结

1716604870241

本章作业

  1. 实现按年级查询学生,功能需求如下 :

    1. 加载年级列表
    2. 默认显示所有学生的信息
    3. 选择年级后,显示该年级学生的信息

    1716604987340

  2. 显示学生成绩,功能需求如下:

    1. 在查询学生用户窗体中,选择一个学生
    2. 通过右键菜单打开添加成绩窗体
    3. 在窗体中显示该学生的所有成绩,效果如下:

    1716605096548

    1716605116399

    实现思路

    1. 获得选中学生的学号
    2. 将学号传递到添加成绩窗体
    3. 检索该学号的所有成绩
    4. 填充数据集,绑定到DataGridView显示
  3. 保存修改后的学生信息,具体需求说明如下:

    1. 需求说明点击“保存”按钮时,弹出确认操作的消息框

    2. 确定后,将修改后的数据更新到数据库

      1716605251411