0

我是 C# 新手,这个问题一定是一个常见问题,但这确实需要我的时间。在这种情况下,我无法在我的项目中走得更远。

我需要的是,我只想通过在 button_Click 事件中调用 form1 中的方法将值从 form2 listview 传递到 form1 文本框。然而,当我单击将触发我的代码的按钮时,我什么也得不到。

遇到的问题:

1:当我声明Form1 f1 = New Form1()时,编译器仍然编译我的方法将在Form2中的Button_Click事件中调用的代码。但是当我单击按钮时,我的文本框中没有发生任何变化。

2:当我将 Form1 声明为 Public Form1 f1; 并单击按钮时,我得到了 NullReferenceException 。

3:我需要将我的 Form2 显示为 ShowDialog();

任何帮助将不胜感激。

我在 Form1 中的代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Globalization;
using System.Threading;

namespace Practice_CS
{
    public partial class Form1 : Form
    {  

        public Form1()
        {
            InitializeComponent();
        }

        private void btnViewList_Click(object sender, EventArgs e)
        {
            Form2 f2 = new Form2();
            f2.ShowDialog();
        }

        public void setFields(string sName,string sAge,string sGender) {
            txtName.Text  = sName;
            txtAge.Text  = sAge;
            txtGender.Text  = sGender;        
        }



    }
}

我在 Form2 中的代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Practice_CS
{
    public partial class Form2 : System.Windows.Forms.Form
    {        

        public Form2()
        {
            InitializeComponent();            
        }

        private void Form2_Load(object sender, EventArgs e)
        {
            lvlist.Items.Add("Juli");
            lvlist.Items[0].SubItems.Add("20");
            lvlist.Items[0].SubItems.Add("Male");

            lvlist.Items.Add("Mark");
            lvlist.Items[1].SubItems.Add("21");
            lvlist.Items[1].SubItems.Add("Male");

            lvlist.Items.Add("Shiela");
            lvlist.Items[2].SubItems.Add("18");
            lvlist.Items[2].SubItems.Add("Female");

        }

        private void btnSelect_Click(object sender, EventArgs e)
        {
            if (lvlist.Items.Count < 1) { return; }

            Form1 f1 = new Form1();
            f1.setFields(lvlist.FocusedItem.Text, lvlist.FocusedItem.SubItems[1].Text,     lvlist.FocusedItem.SubItems[2].Text);
            this.Close();
        }

        private void lvlist_DoubleClick(object sender, EventArgs e)
        {
            btnSelect_Click(btnSelect, e); 
        }

    }
}
4

6 回答 6

3

在 Form2 中添加一个私有字段

private Form1 form1_;

更改构造函数

public Form2(Form1 form1) {
   form1_ = form1;
   InitializeComponent(); 
}

在表格 1

Form2 f2 = new Form2(this);
f2.ShowDialog();

现在您可以使用form1_.setFieldsin Form2(而不是使用 a new Form1,这与“调用”无关Form1

编辑

public Form2() {
   InitializeComponent();
}
public Form2(Form1 form1) : this() {
   form1_ = form1;
}
于 2013-06-04T12:55:18.510 回答
1

解决这个问题(当您将表单称为模式对话框时)的自然方法是保存要通过 form2 上的公共属性传递回 form1 的值。

所以在form2中声明这些属性并在关闭表单时在内部设置它们

public string Name {get; private set;}
public string Age {get; private set;}
public string Gender {get; private set;}

private void btnSelect_Click(object sender, EventArgs e)
{
    if (lvlist.Items.Count < 1) { this.DialogResult = DialogResult.None; return; }
    this.Name = lvlist.FocusedItem.Text;
    this.Age = lvlist.FocusedItem.SubItems[1].Text;
    this.Gender = lvlist.FocusedItem.SubItems[2].Text;
    this.DialogResult = DialogResult.OK;  
}

现在以您的形式1

private void btnViewList_Click(object sender, EventArgs e)
{
    using(Form2 f2 = new Form2())
    {
        if(DialogResult.OK == f2.ShowDialog())
        {
            // At this point f2 is still in memory but it is hidden
            // You could read the public properties exposed by the Form2
            string name = f2.Name;
            string age = f2.Age;
            string gender = f2.Gender;
        }
    } // <- At this point the f2 instance is closed and ready for GC 
}

此方法具有将 Form2 的功能与 Form1 分离的优点。
无需更改 Form2 构造函数或添加另一个构造函数,然后在 Form2 的代码中进行测试,以发现当前需要 Form2 功能的客户端。

通过这种方式,您可以在任何需要的地方创建 Form2 的实例,而无需将其绑定到 Form1 的实例

于 2013-06-04T13:00:40.287 回答
0

您需要在 Form2 中引用 Form1。否则,每个形式都不知道另一个形式的存在。建议:添加对Form1的引用作为Form2的实例变量。像这样:

public partial class Form2
{
    // ... snip
    public Form1 otherForm;
}

这样Form2 可以访问Form1 的成员。然后您可以this.otherForm.someMethod()在 Form2 的代码中使用。

有几点需要考虑:

  • 您仍然必须设置该变量的值,否则它将为空。
  • 大多数人会建议您将该变量设为私有,并将其设置在 Form2 的构造函数中。这也是中肯的建议。
于 2013-06-04T12:56:06.873 回答
0

您的问题是您正在 Form2 的代码中创建 Form1 的新实例。在 Form2 上执行此操作this.Close()时,您将返回到 Form1 的现有实例。

在您的情况下,一个简单的解决方案是将 Form1 实例传递给 Form2 构造函数,如下所示:

new Form2(this);

但是,更合适的解决方案是在 Form2 上公开表示 Form1 应该读取的值的属性。然后,您在 Form1 中的代码可能如下所示:

var form2 = new Form2();
form2.ShowDialog();
this.FieldToSet = form2.SomeProperty;
于 2013-06-04T12:56:37.703 回答
0

最简单的做法是将 Form1 的实例传递给 Form2:

Form2 f2 = new Form2();
f2.Form1 = form1;
f2.ShowDialog();

在 Form2 中,创建如下属性:

public partial class Form2 : System.Windows.Forms.Form
{
    public Form1 Form1 { get; set; }        
}

然后在 Form2 中,您可以使用此实例来调用操作setFields

private void btnSelect_Click(object sender, EventArgs e)
{
    if (lvlist.Items.Count < 1) { return; }   
    Form1.setFields(lvlist.FocusedItem.Text, lvlist.FocusedItem.SubItems[1].Text,     lvlist.FocusedItem.SubItems[2].Text);
    this.Close();
 }
于 2013-06-04T12:56:46.810 回答
0

您应该将对 Form1 的实例的引用发送到 Form2 实例中以实现它。

public partial class Form1 : Form
{ 
    public Form1()
    {
        InitializeComponent();
    }

    private void btnViewList_Click(object sender, EventArgs e)
    {
        Form2 f2 = new Form2(**this**);
        f2.ShowDialog();
    }


public partial class Form2 : System.Windows.Forms.Form
{        
    private Form1 form1;

    public Form2(Form1 form1)
    {
        InitializeComponent();       

        this.form1 = form1;
    }

    ....
    private void btnSelect_Click(object sender, EventArgs e)
    {
        if (lvlist.Items.Count < 1) { return; }

        **form1**.setFields(lvlist.FocusedItem.Text, lvlist.FocusedItem.SubItems[1].Text, lvlist.FocusedItem.SubItems[2].Text);
        this.Close();
    }
于 2013-06-04T12:57:22.550 回答