C#-DataGridView-具有基于内容的唯一CellClick事件

C#-DataGridView-具有基于内容的唯一CellClick事件,c#,datagrid,C#,Datagrid,我有一个设计问题,当用户在DataGridView中单击某个单元格时,根据该单元格中的信息类型,希望发生不同的操作时,最好的方法是什么 想象一下下面的场景。有一个包裹交付系统,其中一个屏幕显示当前计划的所有交付的列表。列可包括: 交货编号 客户编号 客户交货地点 主要联系人 交货单收据 如果用户单击某个单元格,则操作应根据列的内容而有所不同。例如,如果用户单击“客户交货地点”,可能会打开一个交货地点窗口,允许用户查看/编辑地点详细信息。如果用户单击“交货单收据”,可能会打开一个PDF窗口,显

我有一个设计问题,当用户在DataGridView中单击某个单元格时,根据该单元格中的信息类型,希望发生不同的操作时,最好的方法是什么

想象一下下面的场景。有一个包裹交付系统,其中一个屏幕显示当前计划的所有交付的列表。列可包括:

  • 交货编号
  • 客户编号
  • 客户交货地点
  • 主要联系人
  • 交货单收据
如果用户单击某个单元格,则操作应根据列的内容而有所不同。例如,如果用户单击“客户交货地点”,可能会打开一个交货地点窗口,允许用户查看/编辑地点详细信息。如果用户单击“交货单收据”,可能会打开一个PDF窗口,显示订单收据

实现这一点的简单方法是在CellClick事件上执行If语句。伪代码:

If (column = Delivery Order Receipt)
{
    LoadPDF()
} 
Else if (column = Customer Delivery Location)
{
    LaunchDeliveryWindow()
}

我觉得这有点草率。尤其是在某个时间点,程序需要扩展以包括独特的右键单击操作,或者类似的操作。那么代码基本上就必须被复制。有更好的方法吗?让一个类(可能是ColumnActionType)定义哪些操作应该与列相关联,怎么样?

我认为使用switch语句会更好

switch (column) {
   case "Delivery Order Receipt":
      LoadPDF();
      break;
   case "Customer Delivery Location":
      LaunchDeliveryWindow();
      break;
   default:
      break;
   }

其中,dgGridView是DataGridView对象,“dgcCustomer”是DataGridView中的一列,虚线续线是对该单击事件的响应。

在我看来,下面是实现它的好方法。特别是如果列/操作不太多。然而,正如DonBoitnott在评论中指出的那样,这实际上取决于形势

private enum ActionType
{
    CellRightClick,
    CellDoubleClick
    // add as you need them
}    

private void dgv_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
    if (e.RowIndex >= 0)
    {
        DataGridViewColumn selectedColumn = this.dgv[e.ColumnIndex, e.RowIndex].OwningColumn;
        this.PerformActionOnColumn(ActionType.CellDoubleClick, selectedColumn.Name);
    }
}

private void PerformActionOnColumn(ActionType action, string columnName)
{
    switch (columnName)
    {
        case "col_One":
            switch (action)
            {
                case ActionType.CellRightClick:
                    // right click actions for col_One
                    break;

                case ActionType.CellDoubleClick:
                    // double click actions for col_One
                    break;
            }
            break;

        case "col_Two":
            switch (action)
            {
                case ActionType.CellRightClick:
                    // right click actions for col_Two
                    break;

                case ActionType.CellDoubleClick:
                    // double click actions for col_Two
                    break;
            }
            break;
    }
}

其中
dgv
是手头的
DataGridView
。我把它放在
CellDoubleClick
事件中,但是你可以把它放在任何使用
DataGridViewCellEventArgs
的事件中,或者你可以访问当前所选列的任何事件中

问题不在于逻辑机制,而在于设计原则。我想这在很大程度上取决于存在多少选择。如果左键单击“交货单收据”列仅产生一个操作,而其他反应类似于1:1,则您的方法不错。您可以将它封装在一个类中,但在某个时候,您仍然需要决定单击了什么、如何单击以及如何处理它。
private enum ActionType
{
    CellRightClick,
    CellDoubleClick
    // add as you need them
}    

private void dgv_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
    if (e.RowIndex >= 0)
    {
        DataGridViewColumn selectedColumn = this.dgv[e.ColumnIndex, e.RowIndex].OwningColumn;
        this.PerformActionOnColumn(ActionType.CellDoubleClick, selectedColumn.Name);
    }
}

private void PerformActionOnColumn(ActionType action, string columnName)
{
    switch (columnName)
    {
        case "col_One":
            switch (action)
            {
                case ActionType.CellRightClick:
                    // right click actions for col_One
                    break;

                case ActionType.CellDoubleClick:
                    // double click actions for col_One
                    break;
            }
            break;

        case "col_Two":
            switch (action)
            {
                case ActionType.CellRightClick:
                    // right click actions for col_Two
                    break;

                case ActionType.CellDoubleClick:
                    // double click actions for col_Two
                    break;
            }
            break;
    }
}