我是C#的初学者,正在开发HMI(WinForms(。
我有一个充满数据的DataGridView和一些带按钮的列
当我点击该列的按钮时,CellContentClick事件正在触发,我想使用开关案例获得用户点击的精确列:
(简化代码(
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
var senderGrid = (DataGridView)sender;
if (senderGrid.Columns[e.ColumnIndex] is DataGridViewButtonColumn && e.RowIndex >= 0) // if cell button
{
switch (e.ColumnIndex)
{
case Column1.Index: // <- not building because Column1.Index is a variable
// do something
break;
case Column2.Index:
// do something
break;
//etc
default: break;
}
}
}
问题是ColumnX.Index
不能被放入case
条件中,因为它是一个变量。当然,我可以直接使用列索引的编号,但由于我正在开发并总是移动列,所以我希望保持ColumnX.Index
的方式。
交换机在case语句中不能有动态求值语句。必须对它们进行静态评估。
下面的帖子解释了原因:
C#开关语句的限制-为什么?
您也可以使用其他方式,如下链接所述:
还有比这更好的选择吗;开关类型';?
根据您在特定情况下的需要,您还可以使用列的"Tag"属性(它位于DataGridViewBand
上,是DataGridViewColumn
的基础(。当我处理表单时,我经常把按钮应该触发的操作代码放在那里。因此,在列上放置例如Tag="UpdateRecord"
,在代码中可以有
switch (column.Tag as string)
{
case "UpdateRecord":
// Update code
break;
// Other cases
}
通过这种方式,您可以轻松地重新排列网格中的列,而无需修复这些开关。此外(作为实现更干净代码的下一步(,您可以将"UpdateRecord"文本放入某个类的const
中,并在列定义和开关定义中使用它。
您需要使用其他东西-else
或else if
语句可能对您有用。您也可以使用期望值的enum
,并在case
语句中引用它们。
我想保留切换用例方法
好吧,你可以滥用模式匹配:
switch (c.ColumnIndex)
{
case int i when i == Column1.Index:
// do something
break;
case int i when i == Column2.Index:
// do something
break;
//etc
default: break;
}
但我不推荐。