C#开发WinForm之DataGridView开发详解

作者:陈袁 时间:2023-06-25 06:31:35 

前言

DataGridView是开发Winform的一个列表展示,类似于表格。学会下面的基本特征用法,再辅以经验,基本功能开发没问题。

基本的数据渲染

根据提供的数据展示出效果。

提供给DataGridView数据源有很多方式,大致有如下三种:

直接增加,每个单元格类型都是


int index=this.dataGridView1.Rows.Add();
this.dataGridView1.Rows[index].Cells[0].Value = "1";
this.dataGridView1.Rows[index].Cells[1].Value = "2";
this.dataGridView1.Rows[index].Cells[2].Value = "3";

直接增加一行,在行上的每天单元格内添加数据,缺点是太单一

直接增加,但我们可以指定单元格类型


DataGridViewRow row = new DataGridViewRow();
DataGridViewTextBoxCell textboxcell = new DataGridViewTextBoxCell();
textboxcell.Value = "aaa";
row.Cells.Add(textboxcell);
DataGridViewComboBoxCell comboxcell = new DataGridViewComboBoxCell();
row.Cells.Add(comboxcell);
dataGridView1.Rows.Add(row);

可选的类型如下图:

C#开发WinForm之DataGridView开发详解

使用vo对象

上面2种都不是我想要的,因为列表展示的数据大部分情况下是复杂的后台回传的数据。所以我建议使用Vo。
新建InfoVo.cs类


public class InfoVo
{
 /// <summary>
 ///
 /// </summary>
 public string uidItem { get; set; }
 /// <summary>
 ///
 /// </summary>
 public string uidItemRevision { get; set; }
 /// <summary>
 ///
 /// </summary>
 public string primaryTag { get; set; }
}

构造一个List,将InfoVo放进List对象里,然后将List对象赋值给即可。
在窗体的Load事件里添加如下代码


private void SearchInfo_Load(object sender, EventArgs e)
 {
 List<InfoVo> list = new List<InfoVo>();
   list.Add(new InfoVo(){ uidItem="1", uidItemRevision ="1", primaryTag ="1"});
   list.Add(new InfoVo(){ uidItem="2", uidItemRevision ="2", primaryTag ="2"});
   dataGridView.AutoGenerateColumns = false;
   dataGridView.DataSource = null;
   dataGridView.DataSource = list;
 }

直接赋值即可。这里的是禁止dataGridView自动根据vo属性创建列。

在窗体上选中,在属性面板里点击选项。如下图

C#开发WinForm之DataGridView开发详解

在打开的面板里,我们可以创建列。选择是否可见,设置抬头
DataPropertyName:指定列绑定的数据源属性字段。
在DolumnType里我们可以指定单元格类型,如下图

C#开发WinForm之DataGridView开发详解

比如下拉框,或者单元框。
至此,我们可以渲染出DataGridView组件里,下面看一些属性。

dataGridView

列宽自适应


foreach (DataGridViewColumn column in dataGridView.Columns)
{
 column.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
}

成员名称说明
NotSet列的大小调整行为从DataGridView.AutoSizeColumnsMode 属性继承。
None列宽不会自动调整。
AllCells调整列宽,以适合该列中的所有单元格的内容,包括标题单元格。
AllCellsExceptHeader调整列宽,以适合该列中的所有单元格的内容,不包括标题单元格。
DisplayedCells调整列宽,以适合当前屏幕上显示的行的列中的所有单元格的内容,包括标题单元格。
DisplayedCellsExceptHeader调整列宽,以适合当前屏幕上显示的行的列中的所有单元格的内容,不包括标题单元格。
ColumnHeader调整列宽,以适合列标题单元格的内容。
Fill调整列宽,使所有列的宽度正好填充控件的显示区域,只需要水平滚动保证列宽在DataGridViewColumn.MinimumWidth属性值以上。相对列宽由相对DataGridViewColumn.FillWeight属性值决定。

如果想让列宽能按比例填充显示区域则

禁止缩放单元格大小

2个属性

  • :禁止缩放列

  • :禁止缩放行

用户自定义列的顺序

用户可以拖动的方式排序列展示

是否可以编辑单元格

  • 窗体的为

  • 在Columns弹出的列编辑窗口里,选择列的为

  • 为(这是默认值)

行头,列头不显示

在属性面板里选中

列表显示不完全,必需鼠标移到组件上才能显示的bug

将置为false即可。

行头显示行号

为事件添加监听,(在属性面板右边闪电图标下找)。


private void dataGridView1_RowStateChanged(object sender, DataGridViewRowStateChangedEventArgs e)
{
//显示在HeaderCell上
for (int i = 0; i < this.dataGridView1.Rows.Count; i++)
{
 DataGridViewRow r = this.dataGridView1.Rows[i];
 r.HeaderCell.Value = string.Format("{0}", i + 1);
}
this.dataGridView1.Refresh();
}

行号没有完全显示出来的解决办法是将的属性设置为。

禁止自动创建列

如果我们提供的vo对象,dataGrid会自动根据属性创建列,这不是我想要的,我希望能控制显示。如下设置即可

修改单元格类型

单元格可以显示文件,也可以显示单元框,下拉框,图片和超链拉。只要在编辑列窗口里选择ColumnType下拉框,选择一下即可。当然选择的不同,数据设置不同,比如
单选框如下

C#开发WinForm之DataGridView开发详解

下拉框

C#开发WinForm之DataGridView开发详解

选中模式

可以指定选中是整个行被选中还是每个小单元格被选中
SelectionMode,全部可选如下

C#开发WinForm之DataGridView开发详解

其它

当然还有其它,只要我们熟悉,在属性面板上几乎都能找到。

选中事件

CellClick是选中事件,不用它即可,不要用CellContentClick,因为如果单元格无内容,这个CellContentClick事件不会触发。

取得当前单元格内容 :DataGridView1.CurrentCell.Value
取得当前单元格的列 Index:DataGridView1.CurrentCell.ColumnIndex
取得当前单元格的行 Index:DataGridView1.CurrentCell.RowIndex
取得当前行:dataGridView.CurrentRow;
获得绑定的vo


DataGridViewRow dataGridViewRow = dataGridView.CurrentRow;
  InfoVo infoVo = dataGridViewRow.DataBoundItem as InfoVo ;
  infoVo .uidItemRevision ;

如果表格可编辑,那么编辑完表格会同步更新DataBoundItem绑定的vo对象

遍历列表里所有单元格


foreach (DataGridViewRow item in dataGridView.Rows)
  {
    //item是每行的对象,cells是单元格集合
   if (null != item.Cells[0].Value && (Boolean)item.Cells[0].Value)
   {
item.Cells[0].Value.toString();
}
}

使用 DataGridView.CurrentCellAddress 属性(而不是直接访问单元格)来确定单元格所在的
行: DataGridView.CurrentCellAddress.Y
列: DataGridView.CurrentCellAddress.X 。

当前的单元格可以通过设定 DataGridView 对象的 CurrentCell 来改变。可以通过 CurrentCell 来设定
DataGridView 的激活单元格。将 CurrentCell 设为 Nothing(null) 可以取消激活的单元格。

DataGridView DataGridViewCheckBoxColumn编辑时实时触发事件

正常响应事件时,当改变状态时,只有当焦点离开该单元格时才能触发事件,

如果要改变值时实时触发事件,需要借用事件来提交未提交控件的更改。


private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
 {
  if (dataGridView1.IsCurrentCellDirty)
  {
   dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
  }
 }

事实上,当调用时,就提交了当前的修改,很多其它事件都会有响应,其中就是其中之一。
这样事件就可以随着的值的改变实时触发。
以全选/反选为例说明当发生变化时怎么处理全选/反选。
Box有3种状态:选中()/取消()/部分选中()
在winForm组件里拖拽一个命名为selectAllCheckBox,Text为,拖拽一个命名为revSelectLinkLbl,Text为。


//全选
 private void selectAllCheckBox_CheckedChanged(object sender, EventArgs e)
 {
  CheckBox c = sender as CheckBox;
  if(c.CheckState == CheckState.Checked)
  {
   ChangeDataSourceChecked(true);
  }
  else if(c.CheckState == CheckState.Unchecked)
  {
   ChangeDataSourceChecked(false);
  }
 }

private void ChangeDataSourceChecked(Boolean isSelected)
 {
  foreach (SavePlmBomResponseVo savePlmBomResponseVo in dataSource)
  {
   savePlmBomResponseVo.checkedC = isSelected;
  }
  dataGridView.DataSource = null;
  dataGridView.DataSource = dataSource;
 }
 /// <summary>
 /// 反选
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void revSelectLinkLbl_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
 {
  if (this.selectAllCheckBox.CheckState == CheckState.Checked)
  {
   this.selectAllCheckBox.CheckState = CheckState.Unchecked;
  }
  else if(this.selectAllCheckBox.CheckState == CheckState.Unchecked)
  {
   this.selectAllCheckBox.CheckState = CheckState.Checked;
  }
  else
  {
   //部分选中
   foreach (SavePlmBomResponseVo savePlmBomResponseVo in dataSource)
   {
    if (savePlmBomResponseVo.checkedC)
    {
     savePlmBomResponseVo.checkedC = false;
    }
    else
    {
     savePlmBomResponseVo.checkedC = true;
    }
   }
   dataGridView.DataSource = null;
   dataGridView.DataSource = dataSource;
  }
 }

/// <summary>
 /// 处理DataSource数据变化时,全选/反选选中状态
 /// </summary>
 private void calSelectAllCheckBoxState()
 {
  int selectedCount = 0;
  foreach (SavePlmBomResponseVo savePlmBomResponseVo in dataSource)
  {
   if (savePlmBomResponseVo.checkedC)
   {
    ++selectedCount;
   }
  }
  if (selectedCount == 0)
  {
   if(this.selectAllCheckBox.CheckState != CheckState.Unchecked)
   {
    this.selectAllCheckBox.CheckState = CheckState.Unchecked;
   }
  }
  else if (selectedCount == dataSource.Count)
  {
   if (this.selectAllCheckBox.CheckState != CheckState.Checked)
   {
    this.selectAllCheckBox.CheckState = CheckState.Checked;
   }
  }
  else
  {
   if (this.selectAllCheckBox.CheckState != CheckState.Indeterminate)
   {
    this.selectAllCheckBox.CheckState = CheckState.Indeterminate;
   }
  }
 }

/// <summary>
 /// 提交修改状态
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void DataGridView_CurrentCellDirtyStateChanged(object sender, EventArgs e)
 {
  if (this.dataGridView.IsCurrentCellDirty)
  {
   this.dataGridView.CommitEdit(DataGridViewDataErrorContexts.Commit);
  }
 }

//行值变化
 private void DataGridView_CellValueChanged(object sender, DataGridViewCellEventArgs e)
 {
  calSelectAllCheckBoxState();
 }

来源:https://blog.csdn.net/achenyuan/article/details/84632751

标签:C#,DataGridView
0
投稿

猜你喜欢

  • ThreadPoolExecutor中的submit()方法详细讲解

    2022-02-18 03:02:39
  • Spring Cloud微服务架构的构建:分布式配置中心(加密解密功能)

    2021-10-24 05:49:59
  • Java关键字、标识符、常量、变量语法详解

    2023-11-11 20:49:48
  • Android App开发中自定义View和ViewGroup的实例教程

    2021-06-11 08:58:03
  • Android自定义View实现九宫格图形解锁(Kotlin版)

    2022-04-09 11:10:50
  • springmvc中下载中文文件名称为下划线的解决方案

    2023-11-25 22:28:53
  • Android启动相机拍照并返回图片

    2022-06-08 17:29:07
  • Unity3D实现打砖块游戏

    2021-11-13 11:29:44
  • Spring Bean创建流程分析讲解

    2022-04-20 22:53:07
  • Winform开发中使用下拉列表展示字典数据的几种方式

    2022-02-23 11:56:41
  • SpringMvc web.xml配置实现原理过程解析

    2023-04-14 01:42:27
  • SpringBoot 整合 ElasticSearch操作各种高级查询搜索

    2023-03-25 17:12:40
  • Android实现布局全屏

    2023-11-29 06:44:13
  • Android开发之使用150行代码实现滑动返回效果

    2023-03-20 11:08:50
  • Java京东面试题之为什么HashMap线程不安全

    2022-12-06 07:20:02
  • 两个例子了解java中的回调机制

    2023-07-12 21:12:46
  • Android热修复及插件化原理示例详解

    2023-03-07 01:37:52
  • 如何利用Java输出链表中倒数第k个结点

    2022-11-29 10:13:28
  • VisualStudio2019安装C#环境的实现方法

    2021-11-02 18:36:31
  • java web中图片验证码功能的简单实现方法

    2023-06-07 13:30:53
  • asp之家 软件编程 m.aspxhome.com