【问题标题】:How do I set a value if a method is called from a child form?如果从子窗体调用方法,如何设置值?
【发布时间】:2012-02-06 08:58:44
【问题描述】:

我的申请目前有 2 个表格。它创建了一个子表单,Form2,它以以下代码结束:

public partial class Form2 : Form
{ ...
    Form1 frm = new Form1();
        frm.rglu = glu;
        frm.rdate = fulldate;
        frm.sort();
    Close();
}

请注意,form1 目前只是几个按钮。一个从Form2开始如下:

    private void button2_Click(object sender, EventArgs e)
    {
        using (Form2 AcqForm = new Form2())
        {
            AcqForm.ShowDialog(this);
        }
    }

除了稍后显示的按钮test(); 之外,没有其他代码运行)。 这个 frm.sort(); 运行 Form1 中的以下代码:

public partial class Form1 : Form
{
    public void sort() 
    {           
        datelist = new List<DateTime>(rdate);
        datelist.Sort((a, b) => a.CompareTo(b));

        var result = rdate
        .Select((d, i) => new { Date = d, Int = rglu[i] }) 
        .OrderBy(o => o.Date) 
        .ToArray();

        this.rdate = result.Select(o => o.Date).ToArray();
        this.rglu = result.Select(o => o.Int).ToArray();  //all works fine

        for (int i = 7; i+7 <= rglu.Length; i++)
        {
    Console.WriteLine(Convert.ToString(rdate[i]) + Convert.ToString(rglu[i]));
        } //This shows values as expected
    }
}

但是,当我使用 rglurdate 设置按钮以运行更多代码时,出现空指针错误:

public partial class Form1 : Form
{ 
    private void test(object sender, EventArgs e)
    {
        for (int i = 7; i < rglu.Length; i++){} //rglu is null! The values are lost.
    }
}

我相信解决方案需要int[] rglu {get; set;} 方法。但是到目前为止,我根本没有成功使用这些东西。有人遇到过这个问题吗?

编辑: rglu 是这样定义的:

public int[] rglu { get; set; } //I don't get how this works though

【问题讨论】:

  • 在你调用test()之前Sort()被执行了吗?
  • 是的,它被预先调用了。
  • 当您在初始 sn-p 中调用 Close() 时,我想您刚刚关闭了 Form2?您是否在某些未提供的代码中启动了 Form1? test() 方法是在 Form1 上还是 Form2 上?
  • 是的,表格 2 在排序运行后关闭,我相信。测试在表格 1 上。
  • 请您发布class Form1 中定义rglu 的部分吗?

标签: c# arrays winforms


【解决方案1】:

问题在于form2, 你不能写'Form1 frm = new Form1();'这段代码。

在 Form1 中编写如下代码:

using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        public int rglu;
        public DateTime rdate;

        public Form1()
        {
            InitializeComponent();
        }

        private void btnShowForm2_Click(object sender, EventArgs e)
        {
            Form2 frm2=new Form2();
            frm2.Form1Instance = this;
            frm2.Show();
        }
        public void sort()
        {
            datelist = new List<DateTime>(rdate);
            datelist.Sort((a, b) => a.CompareTo(b));

            var result = rdate
            .Select((d, i) => new { Date = d, Int = rglu[i] })
            .OrderBy(o => o.Date) // Sort by whatever field you want
            .ToArray();

            this.rdate = result.Select(o => o.Date).ToArray();
            this.rglu = result.Select(o => o.Int).ToArray();  //all works fine

            for (int i = 7; i + 7 <= rglu.Length; i++)
            {
                Console.WriteLine(Convert.ToString(rdate[i]) + Convert.ToString(rglu[i]));
            } //This returns values as expected
        }
    }
}

在Form2中这样写代码:

using System;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
    public partial class Form2 : Form
    {
        public Form1 Form1Instance;
        public Form2()
        {
            InitializeComponent();
        }

        private void btnSortValues_Click(object sender, EventArgs e)
        {
            Form1Instance.rglu = glu;
            Form1Instance.rdate = fulldate;
            Form1Instance.sort();
            Close();
        }
    }
}

【讨论】:

    【解决方案2】:

    纯粹从防御性编码风格的角度来看,我认为在调用方法之前测试 rglu 是否为 null 是一种很好的做法。

    例如

    public void test() 
    {
        if(rglu == null)
        {
            throw new InvalidOperationException("rglu is null!");
        } 
    
        for (int i = 7; i < rglu.Length; i++){} //rglu is not null!
    }
    

    如果从按钮点击事件中调用 test(),为什么需要公开它。

    【讨论】:

    • 这里的代码比我展示的要多,请原谅我,我正在简化这个问题。 test() 不需要公开。
    【解决方案3】:
    Form1 frm = new Form1();
    frm.rglu = glu;
    frm.rdate = fulldate;
    frm.sort();
    Close();
    

    您不会在其他任何地方使用frm 变量,也不会显示表单,因此在这种情况下,垃圾收集器是唯一将在rdaterglu 变量中接收该数据的人。

    您似乎想对已经存在的表单进行操作。在这种情况下,您必须将对现有 Form1 的引用传递给您在 Form2 中的方法。

    更新:

    它可能看起来像这样:

    public partial class Form2 : Form
    {
        // ...
        private readonly Form1 _parent;
    
        public Form2(Form1 parent) : this()
        {
            _parent = parent;
        }
    
        // ... somewhere in a method which closes Form2:
    
            Form1 frm = _parent;
            frm.rglu = glu;
            frm.rdate = fulldate;
            frm.sort();
            Close();
    
        // ...
    }
    

    要从Form1 显示Form2,请使用

    using(var form2 = new Form2(this))
    {
        form2.ShowDialog(this);
    }
    

    【讨论】:

    • Form1 类型的参数添加到Form2 构造函数将是最简单的方法
    • 这也是我的想法,但这可能是一个非常简化的代码sn-p。如果 Form1 未显示,则无法单击 Test() 按钮,所以我认为我们缺少一些信息。
    • 表格 1 只是空白表格上的 2 个按钮,一个打开表格 2,一个运行 test()。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-05
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    • 1970-01-01
    相关资源
    最近更新 更多