首页 > 解决方案 > C# 从其他任何地方访问在运行时构建的数据表

问题描述

所以我有以下代码:

public partial class Buttons : Form
{
    private DataSet AllEventData = new DataSet("AllEventData");
    private DataTable makeButtonsTable()
    {
        DataTable buttonData = AllEventData.Tables.Add("ButtonData");
        DataColumn column1, column2, column3;

        column1 = new DataColumn();
        column1.DataType = Type.GetType("System.Int32");
        column1.ColumnName = "ID";
        column1.AutoIncrement = true;
        column1.AutoIncrementSeed = 1;
        column1.AutoIncrementStep = 1;

        buttonData.Columns.Add(column1);

        column2 = new DataColumn("Button Name", typeof(String));
        buttonData.Columns.Add(column2);

        column3 = new DataColumn("Button Location", typeof(Rectangle));
        buttonData.Columns.Add(column3);

        buttonData.PrimaryKey = new DataColumn[] { column1 };

        return buttonData;
    }

    public Buttons()
    {
        InitializeComponent();
        DataTable buttonData = makeButtonsTable();
        buttonGridView.DataSource = buttonData;
        buttonGridView.Columns["ID"].Visible = false;  
    }

    private void LaunchScreenSelection_Click(object sender, EventArgs e)
    {
        ss = new ScreenSelection(buttonData);
        ss.Show(this);
    }
}

我的最终目标是让在 ScreenSelection 表单上输入的信息将数据添加到 datagridview,我认为这意味着将其添加到数据表中,但我不清楚。

当我尝试从 LaunchScreenSelection_Click 访问 buttonData 时,它当然会告诉我 buttonData 在当前上下文中不存在。哪个,是的,我有点明白......但考虑到我在这里构建的一切,我不知道如何让它在当前环境中存在。我尝试过的所有事情都会产生更多错误(我很乐意在此处列出所有尝试,但是……那会很长)。

任何帮助,将不胜感激。

标签: c#datagridviewdatatabledataset

解决方案


处理这种情况的正确方法是通过自定义事件。

让我们开始定义一个类,我们将使用它在ScreenLocation表单和Buttons表单之间传输信息。这个类应该是公共的并且对两个表单类(相同的命名空间)都是可见的,它可以在它自己的文件中或者只是附加到 ScreenLocation/Buttons 表单中

public class ButtonData
{ 
    public int ID { get; set; }
    public string Name { get; set; }
    public Rectangle Rect { get; set; }
}

现在我们将添加定义ScreenLocation表单引发的事件所需的样板代码

public class ScreenSelection : Form
{
     public delegate void onDataReady(ButtonData data);
     public event onDataReady DataReady;
     ....
}

此时,我们可以更改ScreenLocation类,添加在数据准备好传输给任何监听事件的人时引发事件的代码。
例如,ScreenLocation 中的 ButtonClick 处理程序可以用这种方式编写

protected void ButtonSave_Click(object sender, EventArgs e)
{
     // Anyone has subscribed to the event?
     if(DataReady != null)
     {
         ButtonData btn = new ButtonData();

         // Change these GetXXXXValue with the appropriate code 
         // that extracts the info from the ScreenLocation UI.
         btn.ID = GetTheIDValue();
         btn.Name = GetTheNameValue();
         btn.Rect = GetTheRectValue();

         // Send the info to the interested parties.
         DataReady(btn);
     }
}

当您从Buttons表单在代码中创建ScreenLocation的实例时,圆圈将闭合。

private void LaunchScreenSelection_Click(object sender, EventArgs e)
{
    ss = new ScreenSelection(buttonData);

    // Tell the ScreenLocation ss instance that we are 
    // interested to know when new data is ready
    ss.DataReady += myDataLoader;
    ss.Show(this);
}

// When the *ScreenLocation* instance will raise the event, 
// we will be called here to handle the event
private void myDataLoader(ButtonData btn)
{
     // Now you have your info from the ScreenLocation instance 
     // and you can add it to the datatable used as datasource for the grid 
     DataTable dt = AllEventData.Tables["AllEventData"];
     dt.Rows.Add(btn.ID, btn.Name, btn.Rect);
}

推荐阅读