我相信有很多方法可以做到这一点。下面是管理进度条的一种可能方法,这样网格列中的“选中”复选框指示进度条的当前值。
如果未选中任何复选框,则进度条将为零。如果选中所有复选框,则进度条将已满。如果选中了一半的复选框,则进度条将显示一半填充。
尚不清楚是否允许用户“添加”行。我将假设在加载网格时行是固定的,并且用户无法将行“添加”到网格中。否则,代码必须在添加行时“更新”进度条的最大值。
当前代码的一小部分......
当前发布的代码有点奇怪,并且做了很多不必要的工作。对于初学者来说,for 循环在某种意义上看起来很奇怪,因为这段代码在网格中执行 CurrentCellDirtyStateChanged 事件……因此,每次单个单元格值变脏或更改时都会触发此事件。所以从技术上讲,只有一 (1) 个单元格发生了变化。当只有一个复选框值可能发生变化时,循环遍历所有复选框值似乎很奇怪。
我认为这是因为代码没有跟踪进度条的当前值。因此,每次单个复选框值更改时都需要计算此值。我有信心,即使不跟踪其当前值,也有一种更简单的方法可以更改进度条值。我正在考虑在选中复选框时向进度条添加 1,并在未选中时减去 1。
此外,当前代码“检查”值的方式很奇怪。 for 循环前有一行……
string A = this.norms_TableDataGridView.Rows[i].Cells[2].Value.ToString();
然后,在for 循环中有一个“检查”来查看A 是否为“真”?
if (A == "True")
这很奇怪,因为A 在循环中从不改变。如果是true,那么在循环中它总是true。 false 也一样。因此,当for 循环退出时,s_Checks++ 将始终为零或等于cnt。
要解决此问题,您需要在每次循环迭代时将A“更改”为下一个复选框值。但是,即使使用此修复程序,代码仍在检查自上次检查以来未更改的值。
同样,可能有更简单的方法。
不同的方法....
我假设加载网格时,所有复选框都未选中,进度条将从零开始。此外,当网格加载数据时,进度条Maximum 的值将设置为网格中(固定)的行数。
使用这种方法,当复选框从“未选中”更改为“选中”时,代码会将进度条值“添加”1。并且,如果“选中”框“未选中”,代码将从进度条值中“减去”1。
为避免错误并保持简单,代码仅检查以确保将 1 加到进度条值不会超过其 Maximum 值。此外,检查以确保减 1 不会低于 Minimum 值。
因此,这种方法将如下所示。一旦加载了未选中所有复选框的网格数据,我们将设置进度条、最小值和最大值。像……
private void Form2_Load(object sender, EventArgs e) {
dataGridView1.DataSource = YourDataSource;
progressBar1.Maximum = dataGridView1.Rows.Count;
progressBar1.Minimum = 0;
}
我没有使用网格CurrentCellDirtyStateChanged 事件,而是使用了网格CellContentClick 事件。
使用CellContentClick 事件的一个问题是,当它触发时,单元格的值还没有改变。我们可以轻松地反转检查逻辑,但是,为了使代码保持可读状态,我将调用网格 CommitEdit 来更新网格中的更改。
在这种情况下,代码会检查复选框是否被选中……在此示例中,复选框位于第 1 列中。
(bool)dataGridView1.Rows[e.RowIndex].Cells[1].Value == true
如果复选框从“未选中”变为“已选中”,则代码会将进度条值加 1,如果复选框从“选中”变为“未选中”,则代码会将其值减 1。
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e) {
if (e.ColumnIndex == 1) {
dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
if ((bool)dataGridView1.Rows[e.RowIndex].Cells[1].Value == true) {
if (progressBar1.Value < progressBar1.Maximum) {
progressBar1.Value++;
}
}
else {
if (progressBar1.Value > 0) {
progressBar1.Value--;
}
}
}
}
我希望这是有道理的。