如何在开关外壳的"case"中使用变量



我是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中,并在列定义和开关定义中使用它。

您需要使用其他东西-elseelse 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;
}

但我不推荐。

最新更新