C#开发WinForm之DataGridView开发

2023-11-19

C#开发WinForm之DataGridView开发

原文 https://blog.csdn.net/achenyuan/article/details/84632751

文章目录

    • [C#开发WinForm之DataGridView开发]
  • [基本的数据渲染]

    • [直接增加,每个单元格类型都是DataGridViewTextBoxCell]
    • [直接增加,但我们可以指定单元格类型]
  • [使用vo对象]

  • [dataGridView]

    • [列宽自适应]
    • [禁止缩放单元格大小]
    • [用户自定义列的顺序]
    • [是否可以编辑单元格]
    • [行头,列头不显示]
    • [列表显示不完全,必需鼠标移到组件上才能显示的bug]
    • [行头显示行号]
    • [禁止自动创建列]
    • [修改单元格类型]
    • [选中模式]
    • [其它]
  • [选中事件]

  • [DataGridView DataGridViewCheckBoxColumn编辑时实时触发事件]

前言

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

基本的数据渲染

根据提供的数据展示出效果。
提供给DataGridView数据源有很多方式,大致有如下三种:

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

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";
1234

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

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

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);
1234567

可选的类型如下图:

在这里插入图片描述

使用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; }
 }
123456789101112131415

构造一个List,将InfoVo放进List对象里,然后将List对象赋值给dataGridView.DataSource即可。
在窗体的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;
        }
123456789

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

在窗体上选中DataGridView,在属性面板里点击Columns选项。如下图
在这里插入图片描述
在打开的面板里,我们可以创建列。选择是否可见,设置抬头
DataPropertyName:指定列绑定的数据源属性字段。
在DolumnType里我们可以指定单元格类型,如下图
在这里插入图片描述
比如下拉框,或者单元框。
至此,我们可以渲染出DataGridView组件里,下面看一些属性。

dataGridView

列宽自适应

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

如果想让列宽能按比例填充显示区域则column.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

禁止缩放单元格大小

2个属性
AllowUserToResizeColumns:true:禁止缩放列
AllowUserToResizeRows:true:禁止缩放行

用户自定义列的顺序

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

是否可以编辑单元格

  1. 窗体的ReadOnly为false
  2. 在Columns弹出的列编辑窗口里,选择列的ReadOnly为false
  3. SelectionMode为RowReadSelect(这是默认值)

行头,列头不显示

在属性面板里选中RowheadersVisible和ColumnHeadersVisible,置为false

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

将RowheadersVisible置为false即可。

行头显示行号

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

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();
}
12345678910

行号没有完全显示出来的解决办法是将DataGridView的RowHeadersWidthSizeMode属性设置为AutoSizeToAllHeaders、AutoSizeToDisplayedHeaders或者AutoSizeToFirstHeader。

禁止自动创建列

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

修改单元格类型

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

下拉框DataGridViewComboBoxColumn
在这里插入图片描述

选中模式

可以指定选中是整个行被选中还是每个小单元格被选中
SelectionMode,全部可选如下
在这里插入图片描述

其它

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

选中事件

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 ;
123
如果表格可编辑,那么编辑完表格会同步更新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();
		}
	}
12345678

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

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

DataGridView DataGridViewCheckBoxColumn编辑时实时触发事件

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

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

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

事实上,当调用dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);时,就提交了当前的修改,很多其它事件都会有响应,其中CellValueChanged就是其中之一。
这样CellValueChanged()事件就可以随着checkbox的值的改变实时触发。
以全选/反选为例说明当DataGridViewCheckBoxColumn发生变化时怎么处理全选/反选。
CheckBox有3种状态:选中(CheckState.Checked)/取消(CheckState.Unchecked)/部分选中(CheckState.Indeterminate)
在winForm组件里拖拽一个CheckBox命名为selectAllCheckBox,Text为全选,拖拽一个LinkLabel命名为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();
        }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C#开发WinForm之DataGridView开发 的相关文章

随机推荐

  • 我的和unity3d的小故事1——恶魔射手之鼠标控制移动之input.getaxis("Horizontal")与input.getaxis("Vertical")

    跟着恶魔射手视频学习的过程中遇到的第一个问题是怎么也移动不了 那么问题来了 打印出来是获得的下面两个值都是0 怎么办呢 改edit下面的projectsetting里面的input属性下面两个值的type都改成mouse movement
  • es head 复合查询_【ES进阶】深入理解Elasticsearch检索评分score执行计划及逆向文档词频idf...

    在前面的课程中 通过搭建ELK相关的中间件 以及配置动态mapping结构用于存储我们需要检索的文档信息 我们通过输入关键词进行分词检索然后ES默认通过评分的形式将数据排序好展示给我们 当文档评分越高 那么搜索的结果越靠前 如下图所示 我们
  • 原型和原型链

    好久没记了有点忘记了 来记录一下 1 函数和对象的关系 对象都是通过函数创建的 函数也是一个对象 2 原型和原型链 1 原型 原型分为两种 prototype 每一个函数都会有prototype属性 它指向函数的原型对象 被称为显式原型 p
  • unity3d之 C# WaitFOrSeconds()

    学习unity3d不久 在使用WaitFOrSeconds 时 遇到了不少麻烦 故记录 以警示后人 首先介绍C 和javascript 在使用它有很大的区别 javascript可以直接使用 yield WaitFOrSeconds 5 即
  • 腾讯云 API 网关产品发布

    欢迎大家前往腾讯云社区 获取更多腾讯海量技术实践干货哦 腾讯云已在近期上线了 API 网关产品 协助开发者通过简单方式即可完成 API 配置管理 发布版本 访问控制等功能 并可进一步对接腾讯云云市场中的 API 市场 参与到 API 经济的
  • 用栈来判断括号匹配问题

    用栈实现 输入一行符号 以 结束 判断其中的括号是否匹配 括号包括 lt gt 如果匹配 输出 right 如果不匹配 给出错误提示 包括 1 对称符号都匹配 输出 right 2 处理到某个符号时不匹配了 输出 The character
  • 美拍应该如何引流?如何利用美拍引流?美拍引流方法

    现如今 抖音 美拍等短视频APP逐渐地在改变人们的生活习惯 很多人在闲暇时都会刷刷短视频 这对于做营销的我们而言 人越多的地方机会就越大 所以肯定是不会放过这个巨大的流量池 那么 我们应该如何利用这些美拍吸粉引流呢 第一步 注册养号 下载了
  • markdown表情大全

    markdown表情 该文是搜集的网络资源整理 为了写博客需要用到一些有趣的表情 特此记录 将对应emoji表情的符号码复制后输入你的markdown文本即可显示emoji表情 如 blush 显示为 人物 syntax preview s
  • 全国大学生数学建模竞赛——大赛介绍与赛后总结

    全国大学生数学建模竞赛 训练过程及赛后总结 前言 今天是2018年9月18日 一个特殊的日子 距离全国大学生数学建模大赛已经过去两天了 三天两夜的比赛 每天晚上几乎做到凌晨 确实很辛苦 但是现在回过头来看看 无论成绩如何 一切的辛苦与努力都
  • ADS2020.2安装

    双击安装包中的 exe文件 开始安装 安装结束后 直接点击退出 然后将crack文件夹中的两个文件夹 分别复制到刚刚的安装路径下 分别替换12个和2个同名文件 注意 这两个文件夹的名字要和刚刚安装的文件夹的名字一致 就是将Crack文件夹中
  • C++头文件

    作为一个二手的 net程序员 你看到了C 头文件一定就犯迷糊了 这到底是个啥玩意 再我纠结了24个小时 google20次 度娘10下 看过10来骗文章以后 我可能稍微开窍了 我对C 头文件总结 与 net比较如下 一 C 头文件究竟是什么
  • onvif协议服务器,Onvif第四课 服务器端发现实现

    场景 需要开发一个服务器发现模块 等待客户端的探测报文 在Linux服务器下组播地址imr interface可以不绑定 mcast imr multiaddr s addr inet addr 239 255 255 250 mcast
  • Python实现企业微信群告警

    Python实现企业微信告警 1 创建企业微信群机器人 1 1 什么是企业微信群机器人 企业微信群机器人是企业微信平台提供的一种功能 可以通过Webhook方式将消息发送到指定的企业微信群中 它可以用于自动化发送通知 告警等信息 实现监控和
  • 证据理论(1)—— DS证据理论基本理论

    证据理论 证据理论 Theory of Evidence 是由 Dempster 首先提出 由Shafer进一步发展起来的一种不精确推理理论 也称为 Dempster Shafer DS 证据理论 证据理论可以在没有先验概率的情况下 灵活并
  • 基于Matlab分析的电力系统可视化研究

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码及数据 1 概述 电力系统可视化研究是电力系统分析中一项具
  • IKE协议与实现

    一 IKE的作用 当应用环境的规模较小时 可以用手工配置SA 当应用环境规模较大 参与的节点位置不固定时 IKE可自动地为参与通信的实体协商SA 并对安全关联库 SAD 维护 保障通信安全 二 IKE的机制 IKE属于一种混合型协议 由In
  • php curl ajax get请求,PHP的curl的get,post请求-Fun言

    GET请求如下 param string url return mixed public function doGet url 初始化 ch curl init curl setopt ch CURLOPT URL url 执行后不直接打印
  • 面试题:从用户在浏览器输入域名,到浏览器显示出页面,这中间发生了什么(工作过程)?

    这是一道很基础的题 但是也容易被忽视 主要是要进行域名解析 1 在浏览器中输入地址 如 www baidu com 2 向DNS服务器查询网站IP地址 3 DNS服务器返回网站IP地址 如 119 75 217 56 4 浏览器得到IP地址
  • 使用pipeline加速Redis

    面试官 怎么快速删除10万个key 某厂面试题 prod环境 如何快速删除10万个key 带着思考 我们一来研究Redis pipeline why pipeline Redis客户端与server的请求 响应模型 前面的文章 Redis底
  • C#开发WinForm之DataGridView开发

    C 开发WinForm之DataGridView开发 原文 https blog csdn net achenyuan article details 84632751 文章目录 C 开发WinForm之DataGridView开发 基本的