简体   繁体   English

麻烦理解 forms 之间的变量 scope

[英]Trouble understanding scope of Variables between forms

Being new to c# I am having trouble understanding how to read from a variable when in a different form.作为 c# 的新手,我无法理解如何以不同的形式读取变量。

Form1:表格1:

namespace SPTimesheets
{
    public partial class Form1 : Form
    {
        public DataTable dtWP = new DataTable("WorkPackHours");
 
       private void GetWorkPackData()
        {
        ...............
        di.Fill(dtWP);
        ................
        }
}

Form2:表格2:

namespace SPTimesheets
{
    public partial class WorkPacks : Form
    {
        public WorkPacks()
        {
            InitializeComponent();
        }

        private void WorkPacks_Load(object sender, EventArgs e)
        {
            dataGridView1.DataSource = Form1.dtWP;
        }
    }
}

I've been reading everything I can find about scope, but I'm obviously missing something.我一直在阅读我能找到的关于 scope 的所有内容,但我显然遗漏了一些东西。 How do I access dtWP from a different form?如何从不同的表单访问 dtWP? The error is "An object reference is required for the non-static field, method or property Form1.dtWP.错误是“非静态字段、方法或属性 Form1.dtWP 需要 object 引用。

It is important to understand what an instance is.了解什么是实例很重要。 We can say:我们可以说:

Form1 foo = null;

Here we have created a reference to Form1 but have not assigned it a value.在这里,我们创建了对 Form1 的引用,但没有为其赋值。 We've said there is a variable named "foo" and it is of type Form1, but we didn't assign it an instance of the object (Form1).我们已经说过有一个名为“foo”的变量,它的类型是 Form1,但我们没有为它分配 object (Form1) 的实例。 Since there is no instance foo will be null.由于没有实例 foo 将是 null。

This is basically what is happening in your WorkPacks Form.这基本上就是您的 WorkPacks 表单中发生的事情。 WorkPacks can see that there is an object of type Form1, but just because it knows the object type doesn't mean it knows the values. WorkPacks 可以看到有一个 Form1 类型的 object,但仅仅因为它知道 object 类型并不意味着它知道这些值。

From the looks of your code WorkPacks doesn't need to know about Form1, it just needs the DataTable from Form1.从您的代码的外观来看,WorkPacks 不需要了解 Form1,它只需要 Form1 中的 DataTable。 To achieve that we can pass the DataTable to WorkPacks when the form is created.为了实现这一点,我们可以在创建表单时将 DataTable 传递给 WorkPacks。

namespace SPTimesheets
{
    public partial class Form1 : Form
    {
       public DataTable dtWP = new DataTable("WorkPackHours");
 
       private void GetWorkPackData()
       {
            di.Fill(dtWP);
       }

       private void btnOpenWorkPacksForm(object sender, EventArgs e)
       {
            // This is where we create a new instance of WorkPacks form and pass the DataTable to the form.
            WorkPacks wp = new WorkPacks(dtWP);
            wp.Show();
       }
}

Now we can overload the constructor to pass in the DataTable.现在我们可以重载构造函数以传入 DataTable。

namespace SPTimesheets
{
    public partial class WorkPacks : Form
    {
        private DataTable _dtWP;
        public WorkPacks()
        {
            InitializeComponent();
        }

        public WorkPacks(DataTable dt)
        {
            InitializeComponent();
            _dtWP = dt; // set our local _dtWP DataTable to the DataTable passed from Form1 (dt)
        }

        private void WorkPacks_Load(object sender, EventArgs e)
        {
            dataGridView1.DataSource = _dtWP;
        }
    }
}

This will be a pretty standard way to pass your values to Forms.这将是一种将您的值传递给 Forms 的非常标准的方法。 If you need a lot of values from Form1 then it is possible to pass the entire form to the new form.如果您需要来自 Form1 的大量值,则可以将整个表单传递给新表单。 However, I would urge against this.但是,我强烈反对这一点。 It would be better to create a class that has properties of the values you want to pass.最好创建一个 class 具有您要传递的值的属性。

public class MyFormProperties
{
    public DataTable dtwp {get;set;}
    public string exampleProperty {get;set;}
}

Then create an instance of this in your starting form and pass it to the new form through the constructor.然后在你的起始表单中创建一个 this 的实例,并通过构造函数将它传递给新表单。

namespace SPTimesheets
{
    public partial class Form1 : Form
    {
       private MyFormProperties _formProperties = new MyFormProperties();
 
       private void GetWorkPackData()
       {
            _formProperties.dtwp.Fill(dtWP);
       }

       private void btnOpenWorkPacksForm(object sender, EventArgs e)
       {
            WorkPacks wp = new WorkPacks(_formProperties);
            wp.Show();
       }
}

namespace SPTimesheets
{
    public partial class WorkPacks : Form
    {
        private MyFormProperties _formProperties;
        public WorkPacks()
        {
            InitializeComponent();
        }

        public WorkPacks(MyFormProperties properties)
        {
           InitializeComponent();
            _formProperties = properties; 
        }

        private void WorkPacks_Load(object sender, EventArgs e)
        {
            dataGridView1.DataSource = _formProperties.dtwp;
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM