问题:全选后删除没有问题,DataGridViewCheckBoxColumn

 
问题:全选后删除没有问题,但是选择了其中几条后,不能将选中的这些记录都删除掉,总是有那么几条删不掉?
请大家帮忙看看我的代码,帮忙纠正,有更好的方法请给出关键代码,谢谢!

datagridview设计如下:第1列是DataGridViewCheckBoxColumn列,其他列是DataGridViewTextBoxColumn列

//代码如下:
using   System;
using   System.Collections.Generic;
using   System.ComponentModel;
using   System.Data;
using   System.Data.SqlClient;
using   System.Drawing;
using   System.Text;
using   System.Windows.Forms;

namespace   test
{
        public   partial   class   Form1   :   Form
        {
                public   Form1()
                {
                        InitializeComponent();
                }
                LinkDB   linkdb   =   new   LinkDB();
                string   strSelectAll   =   "select   *   from   tb1 ";
                string   strTable   =   "tb1 ";
                DataSet   ds   =   new   DataSet();
                private   void   Form1_Load(object   sender,   EventArgs   e)
                {
                        dataGridView1.AutoGenerateColumns   =   false;
                        dataGridView1.AllowUserToAddRows   =   false;
                        dataGridView1.AlternatingRowsDefaultCellStyle.BackColor   =   Color.Azure;
                        ds   =   linkdb.QueryDB(strSelectAll,   strTable);
                        dataGridView1.DataSource   =   ds;
                        dataGridView1.DataMember   =   strTable;
                }

                bool   blIsSelectAll   =   false;
//全选
                private   void   btnSelectAll_Click(object   sender,   EventArgs   e)
                {
                        foreach   (DataGridViewRow   dr   in   dataGridView1.Rows)
                        {
                                ((DataGridViewCheckBoxCell)dr.Cells[0]).Value   =   true;
                        }
                        blIsSelectAll   =   true;
                        return;
                }

//取消全选
                private   void   btnCancelAll_Click(object   sender,   EventArgs   e)
                {
                        foreach   (DataGridViewRow   dr   in   dataGridView1.Rows)
                        {
                                ((DataGridViewCheckBoxCell)dr.Cells[0]).Value   =   false;
                        }
                        blIsSelectAll   =   false;
                        return;
                }

//删除
                private   void   btnDelete_Click(object   sender,   EventArgs   e)
                {
                        try
                        {
                                if   (dataGridView1.Rows.Count   >   0)
                                {
                                        if   (blIsSelectAll)   //全选:进行批量删除
                                        {
                                                for   (int   rowIndex   =   0;   rowIndex   <   ds.Tables[strTable].Rows.Count;   rowIndex++)
                                                {
                                                        ds.Tables[strTable].Rows[rowIndex].Delete();//逻辑性删除(从数据集ds中删除)
                                                        //物理性删除(从DB中删除)
                                                }
                                        }
                                        else   //删除选中了记录
                                        {
                                                for   (int   j   =   0;   j   <   dataGridView1.Rows.Count;   j++)
                                                {
                                                        if   (Convert.ToBoolean(dataGridView1[0,   j].EditedFormattedValue.ToString()))
                                                        {
                                                                ds.Tables[strTable].Rows[j].Delete();//逻辑性删除
//物理性删除
                                                        }
                                                }
                                        }
                                }
                        }
                        catch   (Exception   ex)
                        {
                                MessageBox.Show(ex.Message);
                        }
                }

                private   void   dataGridView1_CellValueChanged(object   sender,   DataGridViewCellEventArgs   e)
                {
                        blIsSelectAll   =   false;
                }
        }
}
 
 
50  修改 删除 举报 引用 回复
id="Topic_Zone" style="HEIGHT: 4px" marginwidth="0" marginheight="0" src="/u/AD/Topic_Zone.aspx" frameborder="0" width="100%" scrolling="no" height="0">
进入用户个人空间
加为好友
发送私信
在线聊天
  • noky
  • 等级:
发表于:2007-04-13 13:44:301楼 得分:0
哈哈,知道你的问题处在那里了,你在用DataGridView等等控件做删除的时候都去循环选中的行或者列进行删除!那你其不知,在循环完成一次后,你的dataGridView1.Rows.Count已经给变了,你在循环删除的时候当然删除不干净了,应为你的循环量已经便利。
解决方法
首先缓存你所选择的行,比如把选择的行存在List <DataGridViewRow>   中,然后循环List进行删除。不要循环DataGridView.Rows.Count进行删除
 
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • noky
  • 等级:
发表于:2007-04-13 13:47:162楼 得分:0
这是一个普遍存在的问题,这种控件有ListBox,DataGridView,DataGrid等等一些控件,不要在用.Count循环进行删除。
 
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
发表于:2007-04-13 13:48:593楼 得分:0
noky:能不能给出代码看看啊
 
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • noky
  • 等级:
发表于:2007-04-13 14:11:024楼 得分:45
for   (int   j   =   0;   j   <   dataGridView1.Rows.Count;   j++)
{
      if   (Convert.ToBoolean(dataGridView1[0,   j].EditedFormattedValue.ToString()))
      {
              ds.Tables[strTable].Rows[j].Delete();//逻辑性删除
//物理性删除
        }
}
改成:
  List <DataGridViewRow>   tmpList   =   new   List <DataGridViewRow> ();
                                for   (int   j   =   0;   j   <   dataGridView1.Rows.Count;   j++)
                                {
                                        if   (Convert.ToBoolean(dataGridView1[0,   j].EditedFormattedValue.ToString()))
{
                                                tmpList.Add(ds.Tables[strTable].Rows[j]);
                                        }
                                }
                                for   (int   i   =   0;   i   <   tmpList.Count;   i++)
                                {
                                        dataGridView1.Rows.Remove(tmpList[i]);
                                }
                                tmpList   ==   null;
 
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
发表于:2007-04-13 14:15:515楼 得分:3
for   (int   rowIndex   =   0;   rowIndex   <   ds.Tables[strTable].Rows.Count;   rowIndex++)
                                                {
                                                        ds.Tables[strTable].Rows[rowIndex].Delete();//逻辑性删除(从数据集ds中删除)
                                                        //物理性删除(从DB中删除)
                                                }

to:

for   (int   rowIndex   =   ds.Tables[strTable].Rows.Count;   rowIndex   > =   0;   rowIndex--)
                                                {
                                                        ds.Tables[strTable].Rows[rowIndex].Delete();//逻辑性删除(从数据集ds中删除)
                                                        //物理性删除(从DB中删除)
                                                }
 
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
发表于:2007-04-13 14:42:356楼 得分:2
删除记录的时候不要从选择记录的第一条开始,因为第一条删除後,后面的index都不对了

所以应该从选择记录的最後一条开始删除
 
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
发表于:2007-04-13 14:48:267楼 得分:0
呵呵   以前也遇到过这个问题     帮   UP   下
 
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
发表于:2007-04-13 14:54:568楼 得分:0
删除记录的时候不要从选择记录的第一条开始,因为第一条删除后
后面的index都不对了,所以应该从选择记录的最后一条开始删除
 
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
发表于:2007-04-13 14:55:199楼 得分:0
noky:你的代码还有点问题啊,我按你那样写了,调试时还有错误!
 
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
发表于:2007-04-13 14:58:4010楼 得分:0
调试好了,谢谢noky!
tmpList=null
 
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
发表于:2007-04-13 14:59:5011楼 得分:0
List <DataGridViewRow>   tmpList   =   new   List <DataGridViewRow> ();
                                                for   (int   j   =   0;   j   <   dataGridView1.Rows.Count;   j++)
                                                {
                                                        if   (Convert.ToBoolean(dataGridView1[0,   j].EditedFormattedValue.ToString()))
                                                        {
                                                                tmpList.Add(dataGridView1.Rows[j]);
                                                        }
                                                }
                                                for   (int   i   =   0;   i   <   tmpList.Count;   i++)
                                                {
                                                        dataGridView1.Rows.Remove(tmpList[i]);
                                                }
                                                tmpList   =   null;
<think>好的,我现在需要帮助用户实现C#中CheckBox控件控制DataGridViewCheckBoxColumn全选和取消全选的功能。根据用户提供的引用和问题,我需要先理解现有的代码示例和用户的具体需求。 首先,用户提到了几个引用,其中引用[1]展示了如何为DataGridView的列头添加CheckBox,引用[2]和[3]则分别演示了通过循环遍历行来设置CheckBox的值。引用[4]则处理了全选和反选时的界面更新,比如改变列头显示符号。用户现在希望用外部的CheckBox控件(不是列头的)来控制DataGridView中所有行的CheckBox列的选中状态。 接下来,我需要考虑如何将外部的CheckBox的CheckedChanged事件与DataGridView中的行操作关联起来。根据引用[2]和[3]的示例,可以通过遍历DataGridView的每一行,根据外部CheckBox的状态设置对应单元格的值。需要注意的是,DataGridViewCheckBoxColumn的值可能存储为布尔类型,也可能用整数表示,比如0和1,这会影响设置时的值类型。例如,引用[2]中使用了0和1,而引用[3]则使用字符串"True"和"False"。因此,需要确认用户的数据类型,或者采用更通用的方式处理。 另外,DataGridView的数据绑定情况也需要考虑。如果DataGridView绑定了数据源,直接修改单元格的值可能不会立即反映到数据源中,需要使用EndEdit或CommitEdit方法提交更改。此外,遍历行时要注意处理新行(通常是最后一行用于添加新数据),避免出现空引用异常,可以通过检查IsNewRow属性来跳过。 还有,用户提到在引用[4]中,切换全选时移动了焦点,以避免复选框列单元格保持焦点状态,这可能影响界面显示。不过用户现在使用的是外部CheckBox,可能不需要处理焦点问题,但需要注意UI的刷新和用户体验。 最后,根据用户的需求,给出步骤说明和示例代码。确保CheckBox的事件处理程序正确绑定,并在代码中正确处理行遍历和值设置。同时,提醒用户可能的注意事项,如数据类型、新行处理和性能优化等。</think>在C#中实现CheckBox控件控制DataGridViewCheckBoxColumn全选/取消全选功能,可通过以下步骤实现: ### 一、基础实现方法 1. **界面布局**:放置一个CheckBox控件(命名为`chkAll`)和DataGridView控件(命名为`dgv`),添加DataGridViewCheckBoxColumn列 2. **事件绑定**:订阅CheckBox的CheckedChanged事件 ```csharp // 初始化代码 public Form1() { InitializeComponent(); chkAll.CheckedChanged += chkAll_CheckedChanged; // 绑定事件[^2] } // 事件处理方法 private void chkAll_CheckedChanged(object sender, EventArgs e) { bool isChecked = chkAll.Checked; foreach (DataGridViewRow row in dgv.Rows) { if (!row.IsNewRow) // 跳过新行[^3] { DataGridViewCheckBoxCell cell = (DataGridViewCheckBoxCell)row.Cells[0]; cell.Value = isChecked; } } dgv.EndEdit(); // 立即提交修改[^4] } ``` ### 二、优化方案 1. **性能优化**:禁用界面刷新 ```csharp dgv.SuspendLayout(); // 循环操作... dgv.ResumeLayout(); ``` 2. **数据类型处理**:明确设置Value类型 ```csharp cell.Value = isChecked ? CheckState.Checked : CheckState.Unchecked; // 适用于CheckState类型[^4] ``` ### 三、注意事项 1. **新行处理**:`row.IsNewRow`判断避免空指针异常[^3] 2. **数据绑定场景**:若使用数据绑定需调用`dgv.CommitEdit(DataGridViewDataErrorContexts.Commit)` 3. **事件触发顺序**:建议设置CheckBox的AutoCheck属性为false,通过代码控制状态变化 ### 四、完整实现示例 ```csharp private void chkAll_CheckedChanged(object sender, EventArgs e) { dgv.SuspendLayout(); try { foreach (DataGridViewRow row in dgv.Rows) { if (row.IsNewRow) continue; var cell = row.Cells["CheckBoxColumn"] as DataGridViewCheckBoxCell; if (cell != null) { cell.Value = chkAll.Checked; } } dgv.EndEdit(); } finally { dgv.ResumeLayout(); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值