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

C#如何在主窗体中响应UserControl的DataGridView双击事件

问题排查与修复方案

1. 构造函数内定义成员的语法错误

你的ucData类把Data属性、DataAvailable事件都写在了构造函数内部,这是C#语法错误,编译器根本无法通过,自然无法正常运行。类的成员(属性、事件、方法)必须定义在类的作用域下,不能放在构造函数中。

修正后的ucData类结构:

public partial class ucData : UserControl
{
    // 属性定义在类级别,而非构造函数内
    public string Data
    {
        get { return textBox1.Text; }
        set { textBox1.Text = value; }
    }

    // 事件定义在类级别
    public event EventHandler DataAvailable;

    public ucData(string Number)
    {
        InitializeComponent();
    }

    /// <summary>
    /// 通知订阅者有新数据可用
    /// </summary>
    /// <param name="e"></param>
    protected virtual void OnDataAvailable(EventArgs e)
    {
        EventHandler eh = DataAvailable;
        eh?.Invoke(this, e); // 用?.简化空引用判断
    }

    private void dataGridView_CellDoubleClick(object sender, EventArgs e)
    {
        OnDataAvailable(EventArgs.Empty); // 传递Empty而非null,符合事件规范
    }
}

2. 事件绑定的实例不匹配

主窗体Test方法里创建的uc是局部变量,如果你实际添加到TabPage的不是这个实例(比如另外新建了一个未绑定事件的ucData对象),那么事件绑定完全不起作用。

确保绑定事件的实例就是最终添加到TabControl的那个:

void Test()
{
    UserControls.ucData uc = new ucData(null);
    uc.DataAvailable += child_DataAvailable; // 简化事件绑定写法
    uc.Data = "Hello!";
    // 必须将该实例添加到目标TabPage中
    tabPage1.Controls.Add(uc);
    uc.Dock = DockStyle.Fill; // 可选,让UserControl填满TabPage
}

void child_DataAvailable(object sender, EventArgs e)
{
    UserControls.ucData child = sender as UserControls.ucData;
    if (child != null)
    {
        MessageBox.Show(child.Data);
    }
}

3. DataGridView的双击事件未正确关联

检查dataGridView_CellDoubleClick方法是否和DataGridView的CellDoubleClick事件绑定:

  • 打开UserControl设计器,选中DataGridView,在属性窗口的事件标签中,确认CellDoubleClick对应的方法是dataGridView_CellDoubleClick。
  • 如果是手动代码绑定,需在构造函数中添加:
public ucData(string Number)
{
    InitializeComponent();
    dataGridView.CellDoubleClick += dataGridView_CellDoubleClick;
}

4. 补充:传递选中行数据的优化

你最终需要传递选中行的对象,目前的Data属性仅获取textBox1的值,建议扩展事件参数来直接传递选中行数据:

// 自定义事件参数类
public class DataSelectedEventArgs : EventArgs
{
    public object SelectedRowData { get; set; }
}

// 修改事件类型
public event EventHandler<DataSelectedEventArgs> DataSelected;

protected virtual void OnDataSelected(DataSelectedEventArgs e)
{
    DataSelected?.Invoke(this, e);
}

private void dataGridView_CellDoubleClick(object sender, EventArgs e)
{
    if (dataGridView.CurrentRow != null)
    {
        // 假设DataGridView绑定了实体类,直接取当前行的绑定对象
        var selectedData = dataGridView.CurrentRow.DataBoundItem;
        OnDataSelected(new DataSelectedEventArgs { SelectedRowData = selectedData });
    }
}

主窗体的事件处理逻辑:

void child_DataSelected(object sender, DataSelectedEventArgs e)
{
    if (e.SelectedRowData != null)
    {
        // 将数据传递到另一个TabPage的控件中
        var targetTab = tabControl1.TabPages["目标Tab页名称"];
        // 假设目标Tab页有一个用于显示详情的UserControl
        var detailControl = targetTab.Controls.OfType<ucDetail>().FirstOrDefault();
        if (detailControl != null)
        {
            detailControl.SetData(e.SelectedRowData);
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 19:51:53