C#从其他任何地方访问在运行时构造的数据表

时间:2019-03-19 21:45:22

标签: c# datagridview datatable dataset

所以我有以下代码:

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。是的,我有点理解...但是鉴于我在这里构建的所有内容,我不知道如何使其在当前上下文中存在。我尝试过的所有操作都会带来更多错误(我很乐意在这里列出所有尝试,但是...会变得冗长)。

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

如果我理解正确,则变量buttonData仅在makeButtonsTable()函数中本地存在。但是,您确实有全局变量 AllEventData ,因为在此处添加了对“ ButtonData”表的引用。

   DataTable buttonData = AllEventData.Tables.Add("ButtonData");

因此,您只需要从AllEventData发送该表作为ScreenSelection的参数即可。

   private void LaunchScreenSelection_Click(object sender, EventArgs e)
   {
     ss = new ScreenSelection(AllEventData.Tables["ButtonData"]);
     ss.Show(this);
   }  

答案 1 :(得分:1)

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

让我们开始定义一个类,我们将使用该类在 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);
}