我有一个扩展 DataGridView 的基类:
public abstract class MyDataGridView : DataGridView
然后我有一个扩展 MyDataGridView 的类。这是类定义和构造函数:
// ::FunctionGridView
public class FunctionGridView : MyDataGridView
{
private static int NUM_COLUMNS = 12;
private static int NUM_ROWS = 1;
public FunctionGridView()
{
// call the method in the base class to setup the grid
setupGridView(NUM_ROWS, NUM_COLUMNS);
}
}
用于我的数据网格的列类型是 DataGridViewCheckBoxColumn 。以下是设置列的代码(在基类中定义):
// ::MyDataGridView
protected void setupGridView(int numRows, int numColumns)
{
for (int i = 0; i < numColumns; i++)
{
DataGridViewCheckBoxColumn column = new DataGridViewCheckBoxColumn();
column.Name = "Column" + (i + 1).ToString();
this.Columns.Add(column);
}
}
我想在用户单击一个单元格然后切换所选单元格的复选框时捕获 SelectionChanged 事件。回调在基类构造函数中设置如下:
// ::MyDataGridView
// initialize the controls then add the event handler
public MyDataGridView()
{
initialize();
this.SelectionChanged += selectionChanged;
}
选择更改回调的定义如下:
// ::MyDataGridView
// get the checkbox _checked_ value and toggle it for the selected cell
private void handleSelectionChanged(object sender, EventArgs e)
{
int currentRow = this.CurrentCell.RowIndex;
int currentColumn = this.CurrentCell.ColumnIndex;
bool cellChecked = (bool)this.Rows[currentRow].Cells[currentColumn].Value;
this.Rows[currentRow].Cells[currentColumn].Value = !cellChecked;
}
一切都很好,除了有一个我不知道如何处理的异常......
当程序启动并构建 DataGridView 并添加到我的 Panel 时,最初会为 Row抛出 SelectionChanged 事件0]。细胞[0] 。即使用户从未真正点击过该单元格,也会调用此事件。
结果是,当我的程序启动时,第一个单元格被检查而没有任何用户点击。我的数据网格视图最终如下所示:
我是否需要一种方法来确定在初始化期间是否抛出 SelectionChanged 回调,而用户单击而不是然后退出我的回调而不切换复选框值?< / p>
// ::MyDataGridView
private void selectionChanged(object sender, EventArgs e)
{
**// if (e.isInitializing()) return;**
....
....
}
我似乎记得在Java ActionEvent 类中,你可以调用 getSource 来确保事件是由控件而不是其他来源触发的。在C#中有没有相同的东西?
============================================ ==================================
注意让我的问题变得简单我使用了基本名称并省略了大部分细节。真正的类/基类名是FunctionKeyTimer和KeyTimer(基类)。如果有帮助,这里是类图和完整的源代码:
public abstract class KeyTimer : DataGridView
{
public static int WIDTH = 640;
public static int HEIGHT = 40;
private bool initialCheckedValue = false;
public KeyTimer()
{
initialize();
this.SelectionChanged += selectionChanged;
}
public KeyTimer(bool initialChecked)
{
this.initialCheckedValue = initialChecked;
initialize();
this.SelectionChanged += selectionChanged;
}
protected void setupGridView(int numRows, int numColumns, string columnNamePrefix)
{
for (int i = 0; i < numColumns; i++)
{
DataGridViewCheckBoxColumn column = new DataGridViewCheckBoxColumn();
column.Resizable = DataGridViewTriState.False;
column.SortMode = DataGridViewColumnSortMode.NotSortable;
column.Name = columnNamePrefix + (i + 1).ToString();
this.Columns.Add(column);
}
for (int i = 0; i < numRows; i++)
{
DataGridViewRow row = new DataGridViewRow();
this.Rows.Add(row);
}
foreach (DataGridViewRow row in this.Rows)
{
for (int i = 0; i < numColumns; i++)
{
row.Cells[i].Value = this.initialCheckedValue;
}
}
}
private void selectionChanged(object sender, EventArgs e)
{
int currentRow = this.CurrentCell.RowIndex;
int currentColumn = this.CurrentCell.ColumnIndex;
bool cellChecked = (bool)this.Rows[currentRow].Cells[currentColumn].Value;
this.Rows[currentRow].Cells[currentColumn].Value = !cellChecked;
}
private void initialize()
{
this.AllowUserToDeleteRows = false;
this.AllowUserToResizeColumns = false;
....
....
}
}
public class FunctionKeyTimer : KeyTimer
{
private static int NUM_COLUMNS = 12;
private static int NUM_ROWS = 1;
private static string COLUMN_NAME_PREFIX = "F";
public FunctionKeyTimer()
{
setupGridView(NUM_ROWS, NUM_COLUMNS, COLUMN_NAME_PREFIX);
}
}
答案 0 :(得分:2)
此问题也会在开箱即用DataGridView
时发生。
标准修复是在DataBindingComplete
事件处理程序中附加选择更改的处理程序。
答案 1 :(得分:1)
好吧,当我使用表单编辑器时,我从未遇到类似事件的问题。在绘制组件之前不会调用事件。
我认为这是因为您在以编程方式选中此框之前添加了事件处理程序。因此,它会被您自己的代码触发。放入一些调试消息以确定操作顺序。它可能就像移动一些函数一样简单。
除此之外,请尝试在事件监听器中打印 sender.name ,以查看它是否在用户检查和程序检查之间发生变化。
我希望有帮助:)
〜丹
答案 2 :(得分:0)
您可以使用:
DataGridViewCheckBoxColumn cb = new DataGridViewCheckBoxColumn();
cb.Name = "The Name";
cb.HeaderText = "The Name";
dataGridView1.Columns.Add(cb);
row.Cells[2].Value = true;
dataGridView1.Rows[0].Cells[6].Value = true;