使用主窗体

时间:2017-05-30 10:15:26

标签: c# winforms oop

我有三种形式,f1,f2,f3,我们称之为。我有一个班级Account,我在其中存储usernamepasswordgroupspath(文件)。 F2是主要形式,应与其他形式互动。 F1是登录表单,F3是编辑表单。我在program.cs中使用它来在其他表单之前调用登录表单。

Form1 login = new Form1();
if (login.ShowDialog() == DialogResult.OK)
{
    Application.Run(new Form2());
}

要在f2f3之间传递数据,我使用带有帐户类的构造函数。但是,我还希望将数据从f1传递到f2,但如果我使用相同的方法,则表单之间没有数据交互(数据为空)。

我编写了上面的代码:

Form1 login = new Form1();
Account acc = new Account();
if (login.ShowDialog() == DialogResult.OK)
{
    Application.Run(new Form2(acc));
}

在登录表单(f1)中,我将一些数据传递给Account类,因此在登录按钮时单击会发生这种情况:

private void LoginButton_Click(object sender, EventArgs e)
{
    Account acc = new Account();
    //some code
    acc.Groups = "New group";
    //some more code
    DialogResult = DialogResult.OK;
}

然后,在Form2.cs中,我有以下代码:

string groups = "";
public Form2(Account acc)
{
    InitializeComponent();
    groups = acc.Groups;
}

但每当我这样运行时,我从未在主窗体中获得任何结果(f2),acc.Groups总是为空,我不知道为什么。我使用与构造函数相同的方法将数据从f2提取到f3,并且它工作正常,为什么这不起作用?是因为我在登录表单中使用了错误的方法吗?处理这个问题的正确方法是什么?

3 个答案:

答案 0 :(得分:1)

问题是您在Account事件中创建了LoginButton_Click的新实例。并且你永远不会将此实例传递给form2!

Form1Account中创建一个字段:

Account my_account;

重载构造函数以将帐户作为参数:

public Form1(Account acc)
{
    my_account = acc;
}

然后在点击事件中引用字段my_account

private void LoginButton_Click(object sender, EventArgs e)
{
    //reference the class variable
    my_account.Groups = "New group";
    //some more code
    DialogResult = DialogResult.OK;
}

在开始时,您需要将Account的起始实例传递给Form1构造函数,以便可以使用值填充:

Account acc = new Account();
Form1 login = new Form1(acc);

if (login.ShowDialog() == DialogResult.OK)
{
    Application.Run(new Form2(acc));
}

详细说明:

创建Account acc = new Account();的实例时,您将获得一个具有内存中特定位置的唯一对象。将此对象传递给Form1的构造函数并将其分配给私有字段my_account时,实际上只传递acc的引用。这意味着您在内存中传递了它的位置。这意味着当您执行此操作时:my_account = acc;在构造函数中确保my_account指向与acc对象相同的位置。通过将字符串分配给my_account来操作Groups的值时,您实际操作原始acc对象。从Form1返回后,再次传递acc对象作为对下一个构造函数的引用。因此,当您在Form2 groups = acc.Groups;中访问此对象时,您将访问已操作的内存中的原始位置以及已为其分配字符串"New group"的位置。

在您发布的代码中,您使用Form1Account acc = new Account();中创建了一个完整的新对象,该对象再次是唯一的,并且与您在一开始创建的对象无关。此对象也位于内存的不同部分,作为第一个acc对象。当您尝试在Groups中访问该属性时,null属性为Form2 我希望这是可以理解的

答案 1 :(得分:0)

我看到你在两个地方创建了新的帐户()(所以你有多个实例),但是你不能将帐户传递给form2。

您可以像Janes在评论中建议的那样使帐户静态化,或者让财产获得帐户。

答案 2 :(得分:0)

在Form1中,声明

public Account Account { get; set; }

在帐户中,声明

 public Form1 Form1{ get; set; }

创建2个对象后登录和acc:

Form1 login = new Form1();
Account acc = new Account();

互相分配

login.Account = acc;
acc.Form1 = login;