Winform DataGridView单元格中动态添加多个控件

简介:

         在DataGridView的单元格中动态添加多个控件。例如在DataGridViewTextBox单元格中,添加CheckBox和Button控件。主题思路就是一个动态控件的大小,位置,显示,事件设置,和平常控件一样使用。

         代码下载链接:https://download.youkuaiyun.com/download/c_gyl/10861487

         如果不熟悉此控件的使用,参考链接:https://blog.youkuaiyun.com/C_gyl/article/details/85067599


效果:

         如下图:

                      


添加

                 AddControl()动态添加控件,绑定事件。

        //添加按钮
        private void AddControl()
        {
            
            dataGridView1.Columns[InfoColumnName].Width = 70;

            for (int i = 0; i < Data.Length; i++)
            {
                TextBox tbx = new TextBox();  
                CheckBox chx = new CheckBox();  //添加CheckBox
                Button btn = new Button();      //添加Button

                //添加
                dataGridView1.Controls.Add(chx);
                dataGridView1.Controls.Add(btn);

                //获取大小
                Rectangle rect = dataGridView1.GetCellDisplayRectangle(ColumnIndex, i, true);
                //大小设置
                tbx.Size = new Size((rect.Width / 3), rect.Height);
                chx.Size = new Size((rect.Width / 3), rect.Height);
                btn.Size = new Size((rect.Width / 3), rect.Height);

                //位置设置
                tbx.Location = new Point(rect.Left, rect.Top );
                chx.Location = new Point(rect.Left + tbx.Width, rect.Top);
                btn.Location = new Point(rect.Left + tbx.Width + chx.Width, rect.Top);

                //绑定事件
                chx.CheckedChanged += new EventHandler(chx_CheckedChanged);
                btn.Click += new EventHandler(btn_Click);

                //属性设置
                chx.Tag = i;
                Chx[i] = chx;
                btn.Tag = i;
                Btn[i] = btn;

            }
        }

1.变量

  1. InfoColumnName是属性DataPropertyName设置的。
  2. ColumnIndex是要添加的列索引。
        DataTable Table = new DataTable();                         //数据,绑定DataGridView
        structData[] Data = new structData[10];                    //数据,长度自行更改
        string NoColumnName = Enum.GetName(typeof(enumData), 0);   //数据源列名
        string InfoColumnName = Enum.GetName(typeof(enumData), 1); //数据源列名
        CheckBox[] Chx = new CheckBox[10];                         //按钮CheckBox
        Button[] Btn = new Button[10];                             //按钮Button
        int ColumnIndex = 1;                                       //要添加在哪一个列的索引

 

2.添加控件

dataGridView1.Controls.Add(chx);

 

3.获取大小

Rectangle rect = dataGridView1.GetCellDisplayRectangle(ColumnIndex, i, true);

 

4.大小设置

  1. 控件的宽,要根据实际需要设置宽。
  2. 控件的高,一般默认原高。
chx.Size = new Size((rect.Width / 3), rect.Height);

 

5.位置设置

  1. 控件的起点X,要根据相邻的起点位置加上相邻的宽。
  2. 控件的起点Y,一般默认原Y。
chx.Location = new Point(rect.Left + tbx.Width, rect.Top);

 

6.事件

  1. 先绑定,和正常控件事件一样,根据实际需要自行更改。
  2. 添加事件。
chx.CheckedChanged += new EventHandler(chx_CheckedChanged);
        private void chx_CheckedChanged(object sender, EventArgs e)
        {
            CheckBox ch = sender as CheckBox;
            int index = int.Parse(ch.Tag.ToString());
            bool value = ch.Checked;
            //Do Something
        }

刷新

            当用到滚动时,还需要把对应的控件显示出来。

        //Scroll事件
        private void dataGridView1_Scroll(object sender, ScrollEventArgs e)
        {
            ControlRefresh(e);
        }

        //更新显示
        //1.滚动时需要启用,否则按钮会看不到
        private void ControlRefresh(ScrollEventArgs e)
        {
         //垂直方向
         if (e.ScrollOrientation == ScrollOrientation.VerticalScroll)
          {
            int curFirstIndex = dataGridView1.FirstDisplayedScrollingRowIndex;
            int disCount = dataGridView1.DisplayedRowCount(true);

            for (int j = 0; j < Data.Length; j++)
            {
                Chx[j].Visible = false;
                Btn[j].Visible = false;
            }
            for (int i = curFirstIndex; i < curFirstIndex + disCount; i++)
            {
                Rectangle rect = dataGridView1.GetCellDisplayRectangle(ColumnIndex, i, true);

                Chx[i].Size = new Size((rect.Width / 3), rect.Height);
                Chx[i].Location = new Point(rect.Left + (rect.Width / 3), rect.Top);
                Chx[i].Visible = true;

                Btn[i].Size = new Size((rect.Width / 3), rect.Height);
                Btn[i].Location = new Point(rect.Left + (rect.Width * 2 / 3), rect.Top);
                Btn[i].Visible = true;
            }
         }
         else  //水平方向
           {
                int curFirstIndex = dataGridView1.FirstDisplayedScrollingColumnIndex;
                int disCount = dataGridView1.DisplayedColumnCount(true);
                int ctlColumn = 1; //控件所在列的位置

                if ( ctlColumn + 1 <= curFirstIndex + disCount)
                {
                    for (int i = 0; i < Data.Length; i++)
                    {
                        Rectangle rect = this.dataGridView1.GetCellDisplayRectangle(ctlColumn, i, true);

                        Chx[i].Size = new Size((rect.Width / 3), rect.Height);
                        Chx[i].Location = new Point(rect.Left + (rect.Width / 3), rect.Top);
                        Chx[i].Visible = true;

                        Btn[i].Size = new Size((rect.Width / 3), rect.Height);
                        Btn[i].Location = new Point(rect.Left + (rect.Width * 2 / 3), rect.Top);
                        Btn[i].Visible = true;
                    }
                }
                else
                {
                    for (int j = 0; j < Data.Length; j++)
                    {
                         Chx[j].Visible = false;
                         Btn[j].Visible = false;
                    }
                }
           }
        }

 

1.Scroll事件

调用ControlRefresh()函数。

 

2.获取当前首行的索引

int curFirstIndex = dataGridView1.FirstDisplayedScrollingRowIndex;

 

3.获取当前显示的行数

 int disCount = dataGridView1.DisplayedRowCount(true);

 

4.大小和位置设置

  1. Size要和AddControl()保持一致。
  2. Location要和AddControl()保持一致。
                Rectangle rect = dataGridView1.GetCellDisplayRectangle(ColumnIndex, i, true);

                Chx[i].Size = new Size((rect.Width / 3), rect.Height);
                Chx[i].Location = new Point(rect.Left + (rect.Width / 3), rect.Top);
                Chx[i].Visible = true;

                Btn[i].Size = new Size((rect.Width / 3), rect.Height);
                Btn[i].Location = new Point(rect.Left + (rect.Width * 2 / 3), rect.Top);
                Btn[i].Visible = true;

 

<think>首先,用户的问题是:“我想查找在winformdatagridview单元格添加按钮的方法”。所以我需要基于提供的引用和之前的系统指令来回答。 回顾提供的引用: - 引用[1]:提到了在WinForm DataGridView单元格动态添加多个控件,比如在文本框单元格添加CheckBox和Button控件。代码下载链接和参考链接。 - 引用[2]:具体提到了在datagridview添加Button按钮的代码实现。 用户明确说“上述引用仅供参考,并不是用户真正的需求”,但我应该尽可能参考用户的问题和我的回答。用户的问题是添加按钮的方法,所以我需要专注于如何在DataGridView单元格添加按钮。 系统级指令: - 回答使用中文。 - 结构清晰,逐步解决问题。 - 确保回答真实可靠。 - 使用$...$或$$...$$格式处理数学表达式(但这里不涉及数学,所以可能不需要)。 - 生成相关问题。 - 引用的段落末尾添加引用标识。 我的回答结构: 1. **介绍方法**:简要说明如何在DataGridView单元格添加按钮。 2. **步骤说明**:提供清晰的步骤,可能包括代码示例。 3. **引用相关**:基于引用[2],添加代码示例,并在末尾添加引用标识。 4. **生成相关问题**:在回答结尾生成相关问题。 从引用[2]中提取关键代码: - 创建一个 `DataGridViewButtonColumn`,设置名称、HeaderText等,然后添加DataGridView的列中。 其他方法: - 用户提到了动态添加多个控件,但这里焦点是添加按钮。我可以提到使用 `DataGridViewButtonColumn` 是一种标准方式。 - 如果不添加整列,而是单个单元格,可能需要使用自定义单元格渲染或事件处理,但引用[2]的方法更适合添加按钮列。 步骤: 1. 使用 `DataGridViewButtonColumn` 添加一个新列,该列的每个单元格都会显示一个按钮。 2. 如果需要动态添加按钮到现有单元格,可以考虑使用 `DataGridViewButtonCell` 或自定义绘制。 基于引用[2],最简单的方法是添加一个按钮列。 回答内容: - 开头确认问题。 - 解释方法。 - 提供代码示例(使用代码块)。 - 添加引用标识。 - 结束时生成相关问题。 代码示例: - 使用引用[2]的代码: ```csharp DataGridViewButtonColumn btn = new DataGridViewButtonColumn(); btn.Name = "btnModify"; btn.HeaderText = "修改"; btn.DefaultCellStyle.NullValue = "修改"; dataGridView1.Columns.Add(btn); ``` 生成相关问题: - 基于上下文,如如何处理按钮点击事件?如何添加按钮到特定行?如何动态添加多个控件? 确保回答真实可靠: - 我熟悉WinForms开发,所以可以确认这个方法是标准的。 - 提醒用户需要处理按钮点击事件等。 完整回答结构: 1. 介绍如何在DataGridView添加按钮列。 2. 提供代码示例。 3. 解释代码。 4. 提到如何处理事件。 5. 添加引用。 6. 生成相关问题。 </think>### 在 WinForm DataGridView 单元格添加按钮的方法 在 WinFormDataGridView 控件动态添加按钮到单元格,通常通过创建专门的按钮列(如 `DataGridViewButtonColumn`)来实现。这是一种标准且高效的方式,确保按钮在单元格内正常显示和响应事件。下面我将分步骤说明具体方法(基于 C# 语言),并参考提供的引用内容。 #### 步骤说明 1. **创建按钮列**:使用 `DataGridViewButtonColumn` 类定义一个按钮列。设置其属性(如名称、标题文本、默认显示值等)。 2. **添加DataGridView**:将该列添加DataGridView 的列集合中。 3. **处理按钮事件**:为按钮添加点击事件处理程序,以响应用户操作。 4. **自定义显示(可选)**:如果需要动态控制按钮的文本、样式或可见性,可以在 `CellFormatting` 事件中自定义。 #### 代码示例 以下代码展示了如何在 DataGridView添加一个按钮列,并处理按钮点击事件。参考引用[2]的实现方式[^2]。 ```csharp // 引入必要的命名空间 using System; using System.Windows.Forms; public partial class Form1 : Form { public Form1() { InitializeComponent(); SetupDataGridView(); } private void SetupDataGridView() { // 创建并添加按钮列 DataGridViewButtonColumn buttonColumn = new DataGridViewButtonColumn(); buttonColumn.Name = "btnAction"; // 列的名称 buttonColumn.HeaderText = "操作"; // 列的标题文本 buttonColumn.Text = "点击"; // 按钮默认显示的文本 buttonColumn.UseColumnTextForButtonValue = true; // 使用列文本作为按钮值 dataGridView1.Columns.Add(buttonColumn); // 添加列到 DataGridView // 添加示例数据行 dataGridView1.Rows.Add("数据1"); dataGridView1.Rows.Add("数据2"); // 绑定按钮点击事件 dataGridView1.CellClick += DataGridView1_CellClick; } // 处理按钮点击事件 private void DataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) { // 检查点击的是按钮列且不是标题行 if (e.ColumnIndex == dataGridView1.Columns["btnAction"].Index && e.RowIndex >= 0) { string cellValue = dataGridView1.Rows[e.RowIndex].Cells[0].Value?.ToString() ?? ""; MessageBox.Show($"您点击了行 {e.RowIndex} 的按钮,对应数据: {cellValue}"); } } } ``` #### 关键解释 - **按钮列类型**:`DataGridViewButtonColumn` 自动将整列的单元格渲染为按钮,无需手动绘制控件。 - **事件处理**:通过 `CellClick` 事件捕获按钮点击,检查列索引(`e.ColumnIndex`)确定是否点击按钮列。 - **动态显示**:如果需要基于单元格数据动态设置按钮文本(如显示“编辑”或“删除”),可在 `CellFormatting` 事件中添加逻辑: ```csharp private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) { if (dataGridView1.Columns[e.ColumnIndex].Name == "btnAction" && e.RowIndex >= 0) { DataGridViewButtonCell cell = dataGridView1.Rows[e.RowIndex].Cells["btnAction"] as DataGridViewButtonCell; cell.Value = "编辑"; // 动态设置按钮文本 } } ``` - **注意事项**: - 确保按钮列添加DataGridView 的列集合后,再添加数据行。 - 如果需要在单个单元格添加多个控件(如按钮 + 复选框),可使用自定义单元格类型(继承 `DataGridViewCell`),但会增加复杂度,引用[1]提供了相关思路[^1]。 #### 引用说明 上述实现参考了 WinForm DataGridView 控件的标准文档和社区实践,代码简单可靠。引用[2]直接提供了添加按钮列的简化方法[^2],而引用[1]讨论了更复杂的动态控件场景[^1]。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值