C#将文本传回主窗体

C#将文本传回主窗体,c#,.net,winforms,C#,.net,Winforms,我正试图打开一个表单,获取用户输入,并将该输入传递回主表单,以便添加到列表中,但我不能对此束手无策。如果有任何有用的建议,都会感谢我所做的错误! 我犯了一个错误 System.NullReferenceException:'对象引用未设置为对象的实例 //Character Class public class Character { private string _Name; public string Name { get { return _Name; }

我正试图打开一个表单,获取用户输入,并将该输入传递回主表单,以便添加到列表中,但我不能对此束手无策。如果有任何有用的建议,都会感谢我所做的错误! 我犯了一个错误 System.NullReferenceException:'对象引用未设置为对象的实例

//Character Class
public class Character {
    private string _Name;

    public string Name {
        get { return _Name; }
        set { _Name = value; }
    }

    public override string ToString() {
        return _Name;
    }
}

//Main Form1
        public List<Character> charList = new List<Character>();
        public EventHandler CharAdded; 

        public void GetData(string name) {
         Character c = new Character();
         c.Name = name;
         charList.Add(c);
       }

        private void btnCreateChar_Click(object sender, EventArgs e) {
        UserInputForm uif = new UserInputForm();

        //Subscribe to events
        CharAdded += uif.btnAdd_Click;

        //Call Event
        if (CharAdded != null) {
            CharAdded(this, new EventArgs());
        }

        //Show Form
        uif.Show();
    }

//UserInputForm
    public void btnAdd_Click(object sender, EventArgs e) {
        Form1 mainForm = sender as Form1;
        mainForm.GetData(txtName.Text); //Error on line
    }
//字符类
公共阶级性质{
私有字符串\u名称;
公共字符串名{
获取{return\u Name;}
设置{u Name=value;}
}
公共重写字符串ToString(){
返回_Name;
}
}
//主要表格1
public List charList=新列表();
公共事件处理程序字符化;
public void GetData(字符串名称){
字符c=新字符();
c、 名称=名称;
添加(c);
}
私有void btnCreateChar\u单击(对象发送者,事件参数e){
UserInputForm uif=新的UserInputForm();
//订阅活动
CharAdded+=uif.btnAdd\u单击;
//呼叫事件
if(CharAdded!=null){
CharAdded(这是新的EventArgs());
}
//表演形式
uif.Show();
}
//用户输入表单
public void btnAdd_单击(对象发送者,事件参数e){
Form1 mainForm=发送方为Form1;
mainForm.GetData(txtName.Text);//第行出错
}

在您的btnAdd\u点击处理程序中,“发件人”的类型为Form1。它是对btnAdd的引用,btnAdd是类型按钮。那么这条线呢

Form1 mainForm=发送方为Form1

将mainForm设置为null,因此出现异常

但主要的问题是你的处理有点倒退。字符甚至应该存在于UserInputForm中,并通过单击UserInputForm上的btnAdd_触发

然后,mainform中的代码变为:

private void btnCreateChar_Click(object sender, EventArgs e) {
        UserInputForm uif = new UserInputForm();

        //Subscribe to events
        uif.CharAdded += Uif_CharAdded;

        //Show Form
        uif.Show();
}

// still in Form1
private void Uif_CharAdded(object sender, EventArgs e) {
  UserInputForm uif = (UserInputForm)sender;
  mainForm.GetData(uif.txtName.Text)
}

此代码仍然不太好,因为它意味着必须公开UserInputForm textName,但希望它能告诉您编写事件代码的方法。

您需要为用户输入表单的Add按钮提供一个事件处理程序,并且您必须在初始化其自己的表单而不是主表单时向此处理程序添加订阅。您还可以从子窗体访问charList。 然后在子窗体中单击“添加”按钮,就可以将新字符添加到charList中

public UserInputForm()
{
    InitializeComponent();
    btnAdd.Click += btnAdd_Click;
}

public void btnAdd_Click(object sender, EventArgs E)
{
    Form2 parent = (this.Parent as Form2);
    parent.charList.Add(txtName.Text);
    this.Close();
}

您的代码有一些含义:

1-
GetData
不清楚应该做什么,在
UserInputForm
中获取控件的名称或
txtName
的文本,似乎要将文本传递到
Form1

2-如果第一个为真,则不应使代码复杂化,只需执行以下操作:

public partial class UserInputForm : Form
{
    public new  Form1 Parent { get; set; }//If you want to replace Parent prop use new keyword otherwise rename Parent prop 
    public UserInputForm(Form1 parent)
    {
        Parent = parent; 
        InitializeComponent();
    } 
    public void btnAdd_Click(object sender, EventArgs e)
    { 
        Parent.SetData(txtName.Text); //Error on line
    } 
}
表格1
中:

public partial class Form1 : Form
{ 
    public List<Character> charList = new List<Character>(); 
    public void SetData(string name)
    {
        Character c = new Character();
        c.Name = name;
        charList.Add(c);
    } 
    private void button1_Click(object sender, EventArgs e)
    {
        UserInputForm uif = new UserInputForm(this);
        uif.Show();
    }  
}
private void btnGetUserInputTextBoxData_Click(object sender, EventArgs e)
{
    var controls = Child.Controls;
    foreach (Character controlName in charList)
    {
        var ctr = (TextBox)controls.Find(controlName.Name, false).FirstOrDefault();
        Console.WriteLine(ctr.Text);
    }
}
和用户输入表单:

public partial class UserInputForm : Form
{
    public new Form1 Parent { get; set; }//If you want to replace Parent prop use new keyword otherwise rename Parent prop 
    public UserInputForm(Form1 parent)
    {
        Parent = parent;
        parent.Child = this;
        InitializeComponent();
    }
    public void btnAdd_Click(object sender, EventArgs e)
    {
        Parent.SetData(txtName.Name); //Error on line
    }
}
5-还有一件事,如果您希望控件的数据存储在
字符列表中
,假设在按钮中单击
表单1

public partial class Form1 : Form
{ 
    public List<Character> charList = new List<Character>(); 
    public void SetData(string name)
    {
        Character c = new Character();
        c.Name = name;
        charList.Add(c);
    } 
    private void button1_Click(object sender, EventArgs e)
    {
        UserInputForm uif = new UserInputForm(this);
        uif.Show();
    }  
}
private void btnGetUserInputTextBoxData_Click(object sender, EventArgs e)
{
    var controls = Child.Controls;
    foreach (Character controlName in charList)
    {
        var ctr = (TextBox)controls.Find(controlName.Name, false).FirstOrDefault();
        Console.WriteLine(ctr.Text);
    }
}

您的用户输入表单是否有文本框和“添加”按钮?那么,在哪里定义了“CharAdded”事件将在子窗体中单击Add按钮时触发?另外,请显示错误堆栈和发生错误的行号。“InitializeComponent”调用是否在UserInputForm的构造函数中正确完成?我假设发生错误时txtName为null。请提供有关
txtName
是什么的信息。这不是我要说的吗//订阅活动CharAdded+=uif.btnAdd\u单击//如果(CharAdded!=null){CharAdded(this,new EventArgs());}您应该将事件移动到UserInputForm。在自己的事件中注册另一个对象是不常见的,也是令人困惑的。你在另一个对象的事件上注册自己。啊,对。当用户单击Add()按钮时。我在想它第一次被叫来的时候,它在哪里。无论如何,使用事件的奇怪方式。事实上,再看一遍,我认为我错了。但是代码很奇怪,我才刚刚醒来