You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#技术问询:如何向构造函数及运行时事件处理程序传参?

解答你的C#技术问题

1. 如何向构造函数传递参数?

构造函数传参是很基础的类初始化操作,只需要在定义类时声明带参数的构造函数,实例化对象时传入对应的值即可。举个直观的例子:

// 定义带参数构造函数的类
public class User
{
    public int Id { get; }
    public string Name { get; }

    // 带参数的构造函数
    public User(int userId, string userName)
    {
        Id = userId;
        Name = userName;
    }
}

// 实例化时传递参数
User newUser = new User(101, "Alice");

如果你的类需要多种初始化方式,还可以重载构造函数,比如同时提供无参和带参版本,满足不同场景的需求。

2. 向运行时生成的事件处理程序传递参数

针对你右键菜单点击需要传递行列索引的场景,我给你两种实用的解决方案,结合你的现有代码来具体说明:

方法一:利用Lambda表达式的闭包捕获变量

闭包可以直接捕获当前上下文的变量,你可以把事件处理逻辑直接写在Lambda里,这样就能直接使用row和column的值(注意要捕获变量的副本,避免闭包引用导致的取值错误)。修改你的DataView_CellMouseDown方法:

private void DataView_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e) { 
    if (e.Button == MouseButtons.Right) { 
        ContextMenuStrip context = new ContextMenuStrip(); 
        int currentMouseOverRow = DataView.HitTest(e.X, e.Y).RowIndex; 
        int row = e.RowIndex; 
        int column = e.ColumnIndex; 
        if (currentMouseOverRow >= 0) { 
            int rowsa = e.RowIndex + 1; 
            int columnsa = e.ColumnIndex + 1; 
            context.Items.Add("Add comment to row: " + rowsa + ", column: " + columnsa); 
        }

        // 捕获当前行列的副本,避免闭包引用问题
        int targetRow = row;
        int targetColumn = column;
        // 用Lambda绑定事件处理逻辑
        context.ItemClicked += (s, eventArgs) => {
            Form1 frm = Application.OpenForms.OfType<Form1>().Take(1).FirstOrDefault(); 
            ToolStripItem clickedItem = eventArgs.ClickedItem; 
            if (clickedItem.Text.Contains("Add comment")) { 
                if (frm != null) {
                    // 直接使用捕获的targetRow和targetColumn
                    frm.DataView.Rows[targetRow].Cells[targetColumn].Value = frm.dataGridView1.Rows[targetRow].Cells[targetColumn].Value.ToString(); 
                }
            }
        };

        // 修正菜单显示位置:用鼠标的像素坐标,而非行列索引
        context.Show(DataView, new Point(e.X, e.Y));
    } 
}

方法二:利用ToolStripItem的Tag属性存储参数

如果需要复用事件处理方法,这种方式更合适。你可以在创建菜单项时,把行列索引存储到菜单项的Tag属性里,然后在事件处理程序中取出使用:

首先,定义一个用于存储行列信息的类(类型更安全,避免使用dynamic带来的潜在问题):

public class RowColumnData
{
    public int RowIndex { get; set; }
    public int ColumnIndex { get; set; }
}

然后修改DataView_CellMouseDown中添加菜单项的代码:

if (currentMouseOverRow >= 0) { 
    int rowsa = e.RowIndex + 1; 
    int columnsa = e.ColumnIndex + 1; 
    // 创建菜单项并存储行列信息到Tag
    ToolStripMenuItem commentItem = new ToolStripMenuItem($"Add comment to row: {rowsa}, column: {columnsa}");
    commentItem.Tag = new RowColumnData { RowIndex = row, ColumnIndex = column };
    context.Items.Add(commentItem);
}

最后修改你的context_ItemClicked事件处理程序:

public static void context_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { 
    Form1 frm = Application.OpenForms.OfType<Form1>().Take(1).FirstOrDefault(); 
    ToolStripItem item = e.ClickedItem; 

    // 从Tag中取出行列信息
    RowColumnData rowColData = item.Tag as RowColumnData;
    if (rowColData != null && frm != null) {
        int x = rowColData.RowIndex;
        int y = rowColData.ColumnIndex;
        if (item.Text.Contains("Add comment")) { 
            frm.DataView.Rows[x].Cells[y].Value = frm.dataGridView1.Rows[x].Cells[y].Value.ToString(); 
        }
    }
}

内容的提问来源于stack exchange,提问作者Jake Doe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:01:19