【问题标题】:How to make dynamically created object's event handler reference a DGV object in another class?如何使动态创建的对象的事件处理程序引用另一个类中的 DGV 对象?
【发布时间】:2020-11-18 04:37:59
【问题描述】:

我创建了一个类dgvRoll,我用它来为运行时分配给Form1 的DataGridView 控件编写动态方法。我还为 DGV 添加了一个滑块控件,并将其安装到一个单元格上。在此处查找视觉参考:

DGV Reference

问题来了,我需要滑块控件的事件处理程序(或在运行时添加到 DGV 的任何通用控件)与 datagridview 进行通信。下面是一个简写示例:

class dgvRoll
{
    public void Loader(DataGridView dataGridView1)
    {
        // REMOVED IRRELEVANT CODE FROM LOADER METHOD
        Dynamic_CTRLs(dataGridView1);
    }

    public void Dynamic_CTRLs(DataGridView dataGridView1)
    {
        Counter = 0; // SET TO ZERO FOR SIMPLICITY
        var sldrCtrl = new RangeSlider();
        sldrCtrl.Name = "sldr" + Counter;

        // ADD CONTROL
        dataGridView1.Controls.Add(sldrCtrl);

        // ADD EVENT HANDLER
        sldrCtrl.Click += new EventHandler(sldrCrtl_Click);
    }

    /* 

这是主要问题:我需要 DATAGRIDVIEW1 来引用 FORM1 中的 DGV 反对创建新的 DGV。我尝试将 DGV 对象作为附加参数传递 在点击事件中,但处理程序不会识别它。 */

    public virtual void sldrCrtl_Click(object sender, EventArgs e)
    {
        RangeSlider sldrCtrl = (RangeSlider)sender;

        // CREATING NEW DGV HERE VERSUS REFERENCING EXISTING DGV IN FORM 1 IS THE PROBLEM
        // POSSIBLE TO ADD ANOTHER OBJECT AS PARAMETER IN CLICK EVENT HANDLER?? 
        DataGridView dataGridView1 = new DataGridView();
        int Diff;
        int sldrCol = 1;
        var rowNum = default(int);
        string name = "sldr";

        try
        {
            Diff = sldrCtrl.Name.Length - name.Trim().Length;
            // ROWNUM IN THIS EXAMPLE EQUALS ZERO
            rowNum = Convert.ToInt32(sldrCtrl.Name.Substring(sldrCtrl.Name.Length - Diff, Diff));
        }
        catch (Exception ex)
        {
        }
        // THROWS NULL REFERENCE EXCEPTION HERE
        dataGridView1.CurrentCell = dataGridView1.Rows[rowNum].Cells[sldrCol];
    }
}

下面是将dgv类分配给Form1中的dataGridView1的代码:

public partial class Form1 : Form
{
    // DGV OBJECT
    DataGridView dataGridView1 = new DataGridView();

    public Form1()
    {
        InitializeComponent();
    }
    private void Form1_Load(object sender, EventArgs e)
    {
        // ASSIGN DGV LOAD METHOD
        dataGridView1.Parent = this.tabCtrl.TabPages[0];
        dataGridView1.Dock = DockStyle.Fill;

        dgvRoll dgv = new dgvRoll();
        dgv.Loader(this.dataGridView1);
    }
}

感谢您的浏览和任何有用的建议!

【问题讨论】:

  • 正确,DataGridView dataGridView1 = new DataGridView(); 不起作用,因为它是“新的”而不是屏幕上的控件。您可以尝试修改 RangeSlider 类以保存对网格控件的引用,并通过构造函数传递网格控件,您将在其中获得 var sldrCtrl = new RangeSlider(dataGridView1);

标签: c# .net datagridview


【解决方案1】:

如果需要,您可以在 Dynamic_CTRLs 方法中将 DataGridView 分配给 RangeSlider 的 Tag 属性,如下所示:

var sldrCtrl = new RangeSlider();
sldrCtrl.Name = "sldr" + Counter;
sldrCtrl.Tag = dataGridView1;//   <-------look here

然后在 sldrCrtl_Click 中这样做:

RangeSlider sldrCtrl = (RangeSlider)sender;
DataGridView dataGridView1 = (DataGridView)sldrCtrl.Tag;

您可以对任何控件执行此操作,只要它是从 Control 类派生的。

【讨论】:

  • 这行得通。谢谢!这是你知道的唯一方法吗?还有,tag属性可以引用多个对象吗?
  • 当然还有其他方法,但要完全按照您的意愿行事(将 dgv 传递给事件处理程序),我认为这是最直接的。 tag 属性只能引用单个“对象”,但该对象可以是列表(如 List)或集合或包含对其他对象的多个引用的类等...只要您知道事件处理程序会发生什么。
  • 顺便说一句,您应该检查一下 (datagridview = (datagridview)sldrCtrl.Tag) 以确保您确实有一个 datagridview。如果它是 null 或其他类型的对象,您将遇到运行时错误,您可能知道。
  • 另一种方法是为您的控件创建包装类,然后创建自定义 EventArgs 类来添加您想要/需要的东西......这需要更多的文本然后在这些 cmets 中允许解释一下,但如果你想做研究,这并不难。不过可能有点矫枉过正。
猜你喜欢
  • 2016-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-19
相关资源
最近更新 更多