2

使用 Windows 窗体,动态创建两个链接标签。当用户点击任何一个链接标签时,就会创建一个动态表单。在该表单中,我创建了一个数据网格、一个文本框和一个动态放置的按钮(在该动态表单中)。现在我想在动态按钮单击事件中访问动态数据网格。我怎样才能做到这一点?

private void Users_Load(object sender, EventArgs e)
{
    da = new SqlDataAdapter("Usp_Get_Employees", con);
    ds = new DataSet();
    da.Fill(ds);

    if (ds.Tables[0].Rows.Count > 0)
    {
        for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
        {
            string somecode = i.ToString() + ds.Tables[0].Rows[i]["eid"].ToString();
            LinkLabel  lbluser  = new LinkLabel();
            lbluser.Name =  ds.Tables[0].Rows[i]["eid"].ToString();
            lbluser.Text = ds.Tables[0].Rows[i]["ename"].ToString();
            lbluser.Location = new System.Drawing.Point(40, i * 40);
            lbluser.Size = new System.Drawing.Size(50, 30);
            Controls.Add(lbluser);
            lbluser.Click += new EventHandler(lbluser_Click);
        }
    }
}


void lbluser_Click(object sender, EventArgs e)
{
    LinkLabel lnkClis = (LinkLabel)sender;
    Form frm = new Form();
    frm.Name = lnkClis.Name;
    frm.Text = lnkClis.Text;
    frm.Show();

    DataGrid dtgrd = new DataGrid();
    dtgrd.Location = new System.Drawing.Point(10, 1 * 40);
    dtgrd.Name = lnkClis.Name;
    names = lnkClis.Name;

    TextBox tx = new TextBox();

    tx.Location = new System.Drawing.Point(10, 5 * 40);
    tx.Size = new Size(80, 30);
    tx.Multiline = true;
    tx.LostFocus += new EventHandler(tx_LostFocus);

    Button btn = new Button();
    btn.Location = new System.Drawing.Point(10, 7 * 40);
    btn.Size = new System.Drawing.Size(50, 30);
    btn.Name = lnkClis.Name;
    btn.Click += new EventHandler(btn_Click);

    frm.Controls.Add(dtgrd);
    frm.Controls.Add(tx);
    frm.Controls.Add(btn);
}

// Now I am trying to access the data grid in the btn_click event

void btn_Click(object sender, EventArgs e)
{
    Button btsave = (Button)sender;
    string eid = btsave.Name;

    object grd = btsave.Parent.Controls.Find("dtgrd", true).FirstOrDefault();

    ((DataGrid)grd).DataSource = ds.Tables[0];
}

现在我在以下位置得到一个对象实例的错误对象集:

((DataGrid)grd).DataSource = ds.Tables[0];
4

4 回答 4

2

您编写的异常消息:

现在我得到一个对象实例的错误对象集

没有意义,但它看起来像

你调用的对象是空的

如果是这种情况,我认为错误在于Find方法调用。根据文件

按其 Name 属性搜索控件并构建一个包含所有匹配控件的数组。

在您的按钮单击处理程序中,您假设网格称为dtgrd,但是在创建网格时,您将其命名为:

dtgrd.Name = lnkClis.Name;

如果您将此行更改为:

dtgrd.Name = "dtgrd";

话虽如此,您应该考虑为按钮单击处理程序使用匿名方法。它将首先消除调用该Find方法的需要。

 void lbluser_Click(object sender, EventArgs e)
{
   //...
    DataGrid dtgrd = new DataGrid();
   //...
    Button btn = new Button();
   //...
    btn.Click += (sender,args)=> dtgrd.DataSource = ds.Tables[0];
于 2012-09-10T09:51:58.360 回答
1

试试下面的代码

    public Form1()
    {
        Form f1 = new Form();

        f1.Text = "New Form";

        TextBox t1 = new TextBox();
        t1.Top = 0;
        t1.Name = "t1";
        t1.Visible = true;
        f1.Controls.Add(t1);

        Button b1 = new Button();
        b1.Top = 30;
        b1.Name = "b1";
        b1.Text = "Click";
        b1.Click += b1_Click;
        f1.Controls.Add(b1);

        f1.Show();
    }

    public void b1_Click(object sender, EventArgs e)
    {
        Button btn = (Button)sender;
        object txt = btn.Parent.Controls.Find("t1", false).First();
        ((TextBox)txt).Text = "Hi, you have clicked me.";
    }
于 2012-09-07T09:51:27.673 回答
1

我稍微修改了 Nitesh 的代码。只需使用 lambda 在点击处理程序中捕获文本框:

public Form1()
{
    Form f1 = new Form();

    f1.Text = "New Form";

    TextBox t1 = new TextBox();
    t1.Top = 0;
    t1.Name = "t1";
    t1.Visible = true;
    f1.Controls.Add(t1);

    Button b1 = new Button();
    b1.Top = 30;
    b1.Name = "b1";
    b1.Text = "Click";
    b1.Click += (sender, args) => MessageBox.Show("The text is: " + t1.Text);
    f1.Controls.Add(b1);

    f1.Show();
}
于 2012-09-07T09:55:08.610 回答
0

您得到的错误来自语句(因为grd对象是null):

((DataGrid)grd).DataSource = ds.Tables[0];

由于您正试图抓住动态控件,因此最好进行适当的空值检查、类型检查和错误处理。像这样的东西:

if(grd != null && grd is DataGrid)
    ((DataGrid)grd).DataSource = ds.Tables[0];
于 2012-09-17T05:48:44.643 回答