c#方法不能工作,同时设置多个值从form2传递给form1

本文关键字:form2 form1 工作 不能 方法 设置 | 更新日期: 2023-09-27 18:16:47

我是c#的新手,这个问题一定是一个常见的问题,但它确实占用了我的时间。在这种情况下,我不能继续我的项目。

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

问题:

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

2:当我声明Form1作为公共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); 
        }
    }
}

c#方法不能工作,同时设置多个值从form2传递给form1

在Form2中添加私有字段

private Form1 form1_;

改变构造函数

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

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

现在您可以在Form2中使用form1_.setFields(而不使用new Form1,这与"调用"Form1无关)

编辑

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

处理此问题(当您将窗体作为模态对话框调用时)的自然方法是保存要通过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;  
}

现在在form1

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的实例

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

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

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

要考虑的几件事:

  • 你仍然需要设置该变量的值,否则它将为空。
  • 大多数人会建议你把这个变量设为private,并在Form2的构造函数中设置它。这也是一个很好的建议。

您的问题是您正在Form2的代码中创建Form1的新实例。当您在Form2上执行this.Close()时,您将返回到已经存在的Form1实例。

在这种情况下,一个简单的解决方案是将Form1实例传递给Form2构造函数,如下所示:
new Form2(this);

然而,更合适的解决方案是在Form2上公开表示Form1应该读取的值的属性。然后,Form1中的代码可能看起来像:

var form2 = new Form2();
form2.ShowDialog();
this.FieldToSet = form2.SomeProperty;

最简单的方法就是将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();
 }

您应该将对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();
    }