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
相关产品推荐
相关产品推荐

