我发现了一些关于在其他表单中使用方法的好帖子,并尝试在我的代码中实现它们,但我得到一个空对象错误(具体来说,frmAddMaterials对象为null)。代码编译正常,尝试使用第二个窗体上的创建材料按钮时发生错误。
我的第一个表单有一个数组来保存材料信息。当用户单击第一个表单上的链接时,系统会提示第二个表单,如果他们感兴趣的材料不在设计中,他们可以输入自定义材料信息。单击表单上的“添加材料” 2,我想在第一个表单上运行RefreshMaterials()方法,它根据第二个表单中的信息在数组中创建一个新条目。
Form1:
public partial class frmSnapFitMain : Form
{
public frmMat frmAddMaterials;
public Materials[] material = new Materials[20];
Image[] problemtype = new Image[7];
private void linkLabel1_LinkClicked_1(object sender,LinkLabelLinkClickedEventArgs e)
{
frmMat frmAddMaterials = new frmMat(this);
frmAddMaterials.Show();
}
public void RefreshMaterials()
{
material[Materials.MaterialCount] = new Materials(frmAddMaterials.txtName.Text, Double.Parse(frmAddMaterials.txtFlex.Text), Double.Parse(frmAddMaterials.txtFriction.Text), Double.Parse(frmAddMaterials.txtStrain.Text)); //little m, materials here is for specific instance
cboxMatSelect.Items.Add(frmAddMaterials.txtName.Text);
frmAddMaterials.txtName.Text = ""; //reset fields
frmAddMaterials.txtFlex.Text = "";
frmAddMaterials.txtFriction.Text = "";
frmAddMaterials.txtStrain.Text = "";
}
}
表格2:
public partial class frmMat : Form
{
private readonly frmSnapFitMain _form1;
public frmMat(frmSnapFitMain Form1)
{
InitializeComponent();
this._form1 = Form1;
}
public void btnCreate_Click(object sender, EventArgs e)
{
this._form1.RefreshMaterials();
this.Close();
}
public void frmMat_Load(object sender, EventArgs e)
{
}
}
答案 0 :(得分:0)
在linkLabel1_LinkClicked_1
方法中,您声明了frmMat
的新实例。这个实例恰好与全局变量具有相同的名称,但它是一个本地变量,当您退出该方法时它会消失。
private void linkLabel1_LinkClicked_1(object sender,LinkLabelLinkClickedEventArgs e)
{
// This is not the global variable frmAddMaterials.
// It is a local one to this method
frmMat frmAddMaterials = new frmMat(this);
frmAddMaterials.Show();
}
当然这意味着您在 RefreshMaterials 中使用了从未初始化的全局变量
您只需要删除局部变量的声明并初始化全局变量
private void linkLabel1_LinkClicked_1(object sender,LinkLabelLinkClickedEventArgs e)
{
// This initializes the global variable
frmAddMaterials = new frmMat(this);
frmAddMaterials.Show();
}
说使用全局变量并测试变量是否已正确初始化时,使用'防御性编程态度'始终是一个好习惯。
public void RefreshMaterials()
{
if(frmAddMaterials != null)
{
material[Materials.MaterialCount] = new Materials(.....)
cboxMatSelect.Items.Add(frmAddMaterials.txtName.Text);
frmAddMaterials.txtName.Text = ""; //reset fields
frmAddMaterials.txtFlex.Text = "";
frmAddMaterials.txtFriction.Text = "";
frmAddMaterials.txtStrain.Text = "";
}
}
我还建议订阅FormClosing
frmAddMaterials
事件,以便在表单关闭时将您的实例设置为null
private void linkLabel1_LinkClicked_1(object sender,LinkLabelLinkClickedEventArgs e)
{
if(frmAddMaterials != null)
{
frmAddMaterials = new frmMat(this);
frmAddMaterials.Show();
frmAddMaterials.FormClosing += frmMaterialsClosing;
}
}
private void frmMaterialsClosing(object sender, CancelEventArgs e)
{
frmAddMaterials = null;
}
这允许您重新启动'循环',因为再次单击linklabel时,您的全局变量为null,您可以将其重新初始化为在linklabel click事件处理程序中创建的新实例。