2012-08-18 99 views
3

[C#,Visual Studio 2008中,Windows 7的64]C#的DataGridView(复选框)单击单元格多个回调

我有一个的DataGridView在我的课。此数据网格视图使用DataGridViewCheckBoxColumn,以便每个单元格包含一个复选框。

这里是行的一个截图:

DataGridView Checkboxes

我希望能够,如果用户选择(在复选框的顶部某处细胞,但没有)的细胞来检测。我也想检测我用户选择复选框。为了做到这一点我的代码必须为这两个事件设置回调:

this.CellClick += cellClick; // callback when the user selects a cell 
this.CellContentClick += cellContentClick; // callback when the user selects a checkbox 

这里是回调方法:

private void cellContentClick(object sender, DataGridViewCellEventArgs e) 
    { 
     toggleCellCheck(e.RowIndex, e.ColumnIndex); 
    } 

    private void cellClick(object sender, DataGridViewCellEventArgs e) 
    { 
     toggleCellCheck(e.RowIndex, e.ColumnIndex); 
    } 

    private void toggleCellCheck(int row, int column) 
    { 
     bool isChecked = (bool)this[column, row].EditedFormattedValue; 
     this.Rows[row].Cells[column].Value = !isChecked; 
    } 

注:正如你可以看到toggleCellCheck方法获取复选框值并切换它,选中 - >取消选中或取消选中 - >选中)。

当用户单击不是复选框的单元格中的任何位置时,只会触发一个回调,cellClicktoggleCellCheck方法随后被调用并且复选框状态翻转。

这是我想要的确切行为。

我遇到的问题是,当用户直接点击复选框事件得到以下顺序触发:cellClick然后cellContentClick

执行这两个回调都会导致复选框被检查状态在第一次回调后切换,然后在第二次回调后再次切换。当然最终结果是复选框检查状态不变。

有什么办法可以配置DataGridView类来阻止两个回调被触发吗?或者说,是有办法,我可以检测(在cellContentClick方法中),这是回调,或者是通过点击复选框产生的回调,而无需调用toggleCellCheck然后就退出?

我想类似如下:

private void cellContentClick(object sender, DataGridViewCellEventArgs e) 
{ 
    // if sender/sender child/etc. is of type checkbox then return because 
    // _cellClick_ has already been called to change the checkbox checked property 
    // something like the following: 
    // 
    // if (typeof(sender) == CheckBox) return; 
    // else toggleCellCheck(e.RowIndex, e.ColumnIndex); 
} 

谢谢!

+0

更新...我找到了一种方法来规避这种行为。这是一个主要的黑客攻击,但它的工作原理...我使用了一个布尔变量,在_cellClicked_方法中被设置为true。然后,在_cellContentClick_方法中,我检查这个布尔值。如果它是真的(复选框已经改变),那么我退出该方法。否则,我切换复选框状态。这不是一个优雅的解决方案,但至少它是一个可行的解决方案。 (我仍然乐意提供更好的方法来做到这一点!) – 2012-08-18 17:07:41

+0

您不应该需要单元格内容点击处理程序 - 选中复选框时会调用单元格单击。 – 2012-08-20 14:39:18

回答

3

你不应该需要的单元格的内容单击处理程序 - 选中该复选框,当单击单元格被调用。

看来您的最终目标是让网格响应被点击的单元格内容以及实际复选框beong点击。

要做到这一点,只需连接到电池click事件像这样的东西:

void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) 
{ 
    if (dataGridView1.Columns[e.ColumnIndex].Name == "checkboxcolumn") 
    { 
     Console.WriteLine("Click"); 
     bool isChecked = (bool)dataGridView1[e.ColumnIndex, e.RowIndex].EditedFormattedValue; 
     dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = !isChecked; 
     dataGridView1.EndEdit(); 
    } 
} 

1.我会建议对这种UI修改的 - 默认的行为像控制DataGridView广泛传播和测试。改变他们通常是一个坏主意。

+0

+1谢谢!关于你的脚注:我不认为DataGridView是通过触摸屏测试的! – Blorgbeard 2013-05-08 00:01:23

0
private void dataGridView2_CellContentClick(object sender, DataGridViewCellEventArgs e) 
{ 
    DataGridViewCheckBoxCell dgvcell = (DataGridViewCheckBoxCell)dataGridView2[e.ColumnIndex, e.RowIndex]; 
    if ((Convert.ToBoolean(dataGridView2[e.ColumnIndex, e.RowIndex].Value) == true)) 
      { 
       dgvcell.Value = CheckState.Unchecked; 
       lst_box2.Items.Add(dataGridView2.Rows[e.RowIndex].Cells["ItemName"].Value.ToString()); 
       lst_box1.Items.Remove(dataGridView2.Rows[e.RowIndex].Cells["ItemName"].Value.ToString()); 
      } 
      else 
      { 
       lst_box1.Items.Add(dataGridView2.Rows[e.RowIndex].Cells["ItemName"].Value.ToString()); 
       lst_box2.Items.Remove(dataGridView2.Rows[e.RowIndex].Cells["ItemName"].Value.ToString()); 
       dgvcell.Value = CheckState.Checked; 
      } 

} 
相关问题