1

我有两个表单:MainForm并且OptionsForm,其中有一个按钮 ( OK),用于在 MainForm 上应用一些更改。当我第一次打开 OptionsForm 时,一切正常,使用默认值。

在我进行一些更改并单击“确定”后,选项被应用,但是当我第二次打开 OptionsForm 时,我想保留以前的值,而不是像它发生的那样的默认值。

OptionsForm 像这样通过 MainForm 打开

OptionsForm formOptions = new OptionsForm();
if (formOptions.ShowDialog(this) == DialogResult.OK)
{
    // etc..
}

//...

public string otherLabel
    {
        get { return formMainLabel.Text; }
        set { formMainLabel.Text = value; }
    }

在 OptionsForm 我有一个 NumericUpDown 并想保持它的价值

private MainForm mainForm = null;
public OptionsForm(Form callingForm)
{
    mainForm = callingForm as MainForm;
    InitializeComponent();
}
// ...
private void btnOK_Click(object sender, EventArgs e)
{
     this.mainForm.someLabel= someBox.Value.ToString(); // NumericUpDown
     this.mainForm.otherLabel = "abc";       //>>> Getting NullReferenceException
     this.Close();
}

现在我可以保留我的设置,但我得到了一个NullReferenceException. 我试过了,但它仍然无法正常工作。有什么建议吗?

4

6 回答 6

5

ShowDialog() 已经支持这一点。它与 Show() 不同,除了它是模态的之外,它还可以防止表单对象在用户关闭它时被释放。因此,您可以简单地再次调用 ShowDialog(),控件保持其原始值:

    private OptionsForm options = new OptionsForm();

    private void button1_Click(object sender, EventArgs e) {
        if (options.ShowDialog(this) == DialogResult.OK) {
            // etc..
        }
    }

    protected override void OnFormClosed(FormClosedEventArgs e) {
        options.Dispose();
        base.OnFormClosed(e);
    }
于 2013-09-04T18:12:27.120 回答
1

如果您只想保留一个数字上/下控件的值,则只需将其作为构造函数中的参数传递..

public FormOptions(MainForm -mainFrm, int curNumericValue)
{
    someBox.value = curNumericValue;
}

并使用 MainForm 中的值实例化表单

private void button1_click(....)
{
    FormOptions formOptions = new FormOptions(this, Convert.toInt32(someLabel.text));
    formOptions.ShowDialog();
}
于 2013-09-04T18:30:15.097 回答
1

好吧,您应该将这些值传递给 OptionsForm,随意为 OpptionsForm 编写自定义构造函数并在需要时调用它。

于 2013-09-04T17:52:47.567 回答
1

一种方法是始终保留对您的 FormOptions 的引用并显示相同的实例,而不是每次都创建一个新实例。或者,如果您不想这样做,您可以创建一个 Options 类来存储您的所有选项,然后可以将其存储并传递到您之后创建的任何新实例中。两者都有优点和缺点,因此请随意选择最适合您需求的选项。

public class MyOptions
{
    public String StringOption { get; set; }
    public int IntOption { get; set; }
}

然后,您的 FormOptions 将具有 MyOptions 属性,您可以在其中设置所有选项并检索它们。

public class FormOptions : Form
{
    ...
    private MyOptions _options;
    public MyOptions Options 
    {
        get { return _options;}
        set
        {
            _options = value;
            // Set the Form's control values accordingly.
        }
    }
    ...
}

最后,您可以在代码中这样称呼它:

    FormOptions optionsForm = new FormOptions();
    MyOptions savedOptions = new MyOptions(); // Probably don't want to create a new instance every time but I'm sure you get the idea here.
    optionsForm.Options = savedOptions;
    optionsForm.ShowDialog();

    // Get the new options after the form is closed.
    savedOptions = optionsForm.Options;
于 2013-09-04T18:12:10.400 回答
0

似乎您正在从这样的单击事件中调用选项表单的实例:

button1_click(object sender, EventArgs e)
{
    OptionsForm optForm = new OptionsForm();
    optForm.showDialog();
}

您必须在 Mainform 类中为选项表单类创建变量,在那里或在构造函数中实例化它,并且只在事件中调用ShowDialog()orShow()方法。button_Click像这样:

partial class MainForm:Form
{
    OptionsForm optForm;
    ............
    ............
    public MainForm()    //Constructor
    {
        initialiseComponent();
        optForm = new OptionsForm();
        ........
    }

    .......

    private button1_Click(object sender, EventArgs e)
    {
        optForm.Show();    // or ShowDialog()
    }
}

并在选项表单中使用 this.hide() 而不是 this.close() .. 否则表单会被丢弃..

于 2013-09-04T18:01:09.307 回答
0

为什么不直接使用构建属性中可用的“设置”和 WinForms 本身呢?只需让您的设置表单自己填充这些变量,然后在单击“确定”时“设置”它们。然后在 SettingsForm 完全关闭后从这些设置中刷新 MainForm。简单,没有混乱,并且表单之间没有传递变量。

概述:http: //msdn.microsoft.com/en-us/library/k4s6c3a0.aspx

SO问题涵盖设置: 在.NET Winforms应用程序中保存设置

它还具有额外的好处,即值将在应用程序的会话之间保存。

于 2013-09-04T18:27:31.673 回答