2009-09-21 64 views
2

我有两种形式(Form1和Form2)。在Form1上有一个'public int i'变量,它在Form1构造函数中设置为值1。 然后我打开窗体2从Form1中使用此代码:通过两个表单之间的引用传递参数

Form2 f2 = new Form2(ref i); 
f2.ShowDialog(); 

窗体2的构造是这样的:

public int i; 
public Form2(ref int x) 
{ 
    InitializeComponent(); 
    i = x; 
} 

然后我把我在Form2变量值2和关闭窗体2。现在我期望Form1上的变量i具有值2(因为'ref'关键字通过传递参数),但值仍然是1.我做错了什么,为什么ref关键字不工作在我的例子中?

感谢

回答

6

实际发生了什么。

  1. 您创建一个名为整数成员的object1“我”
  2. 你传递一个参考,以“我”到一个新的对象构造。对“我”的引用被称为“x”。
  3. 将“x”的值复制到第二个对象(也称为“i”)中的变量中。
  4. 您退出object2的构造函数。 object1.i的引用在此结束。
  5. 您修改object2.i(它是object1.i的副本,但不是引用,指针或链接)。 object1.i没有被修改。

有很多方法可以通过事件或传入一个将在object1和object2之间共享的对象来实现您想要的内容。

Class Form1 
{ 
    Object i = new Object(); 
    ... 
    public void DoSomething() 
    { 
     Form2 f = new Form2(i); 
     f.Show(); 
    } 
} 

这可能是最简单的方法来完成你要去的东西。

+0

我认为,如果传递整数与ref关键字,它是传递对象相同的东西。感谢您清除 ,它现在起作用。 – sventevit 2009-09-21 13:21:09

+0

您也可以传递一个表单引用/实例而不是Object i – Jan 2016-12-19 12:49:48

6

的“裁判”修改不仅使构造函数调用本身中的任何差异。它只与参数 ...相关联,并且在构造函数完成之后,该参数不再存在。

当您执行的任务:

i = x; 

,这只是复制。它不以任何其他方式将变量ix关联。作为一般的经验法则:如果你不改变方法/构造函数中的参数值(在你的例子中你不这样做),ref修改器没有做任何事情。

你不能做你想做的事:你不能做一个字段(在这种情况下是Form2。i)某个其他变量的别名。

+0

我想补充一点,Form2已经暴露了一个public int i,所以他应该:从构造函数中删除参数,设置f2.i = i;并在ShowDialog()读取后与我= f2.il – configurator 2009-09-21 13:39:20

+1

我真的希望真正的代码*没有*有一个公共领域,但...该类并不真正叫做Form2,要么:) – 2009-09-21 13:41:14

0
i = x; 

此声明将i的值复制到x的值。要更改x,您需要在构造函数中为其指定一个值。例如。

x=2; 
0

ref keyword作用域仅在声明方法内:Form2构造函数。 一旦该方法退出,我在form1和我在form2不再链接(特别是因为它们是ValueType)

0

我不知道你这样做的原因,但我怀疑从对话框窗体中返回一个值并使用它来设置调用类中的变量会更好。否则,您会添加不必要的耦合到您的表单。

+0

如何将Form2中的值返回给Form1? – sventevit 2009-09-21 13:22:16

1

我同意Martin的说法,这种类型的解决方案会增加不必要的耦合,但是如果你仍然坚持让它像这样绑定,我认为使用一个简单的指针就可以做到这一点。

class Form1 { 
    public int i; 
    public void doSomething(){ 
    Form2 f = new Form2(&i); 
    f.showDialog(); 
    } 
} 

然后在Form2中,您只需使用该指针。

class Form2 { 
    public int *i; 
    public Form2(int *r){ 
    InitializeComponent(); 
    i = r; 
    } 
    public void setI(int v){ 
    *i = v; 
    } 
    public int getI(){ 
    return *i; 
    } 
} 

记住要记住所有这些内存管理。

0

感谢答案...

现在,我发现三种方式可以从窗体2取回变量到Form 1:

  • ,而不是正常的整数,传递形式之间的对象
  • 在Form1中,我可以使用get和set方法将'private int myVariable'和属性'public int MyVariable'。然后,我可以把我的整个Form1以窗体2的构造,在那里我可以访问Form1.MyVariable财产
  • 指针

是否有任何其他的选择吗?这三个选项哪一个更好? (在我的例子,我需要从窗体2只能访问一个整数到Form)

感谢

2

如果你真的希望能够从窗体2中你可以使用一个回调方法设置在Form1中的变量。 (即通过在用于设置在Form1变量和从窗体2运行它的方法的地址)

像这样:

public partial class Form1 : Form 
{ 
    public delegate void FormReturn(string s); 
    private string var1; 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     var frm = new Form2(ReturnFunc); 
     frm.ShowDialog(); 
    } 

    protected void ReturnFunc(string text) 
    { 
     var1 = text; 
    } 
} 

public partial class Form2 : Form 
{ 
    private Form1.FormReturn returnFunc; 

    public Form2(Form1.FormReturn del) 
    { 
     InitializeComponent(); 
     returnFunc = del; 
    } 

    private void btnClose_Click(object sender, EventArgs e) 
    { 
     returnFunc.Invoke(txtText.Text); 
     Close(); 
    } 
} 

主要矫枉过正虽然。你可以在form1上设置一个公共属性。

+0

非常有用! 10倍 – oCcSking 2014-01-16 19:46:36