c# winforms。存储和调用控件时出现问题

问题描述 投票:0回答:1

所以我有两个表单,一个父表单和一个子表单,以及一个自定义控件。

父窗体有一个空的自定义控件列表和一个调用子窗体的按钮。

子窗体有一个用于向 TableLayoutPanel 添加/删除自定义控件的按钮,一个用于将自定义控件保存到父窗体列表中的按钮,以及一个用于将保存的控件调用到 TableLayoutPanel 的按钮。

自定义控件是一个带有单行组合框和文本框的 TableLayoutPanel。

我想要做的是,每当我在子窗体中单击“保存”时,控件都会保存到父窗体的列表中并关闭子窗体。当我调用新的子窗体时,子窗体将能够使用保存的控件填充其 TableLayoutControl。

我遇到的问题是,虽然控件确实保存到列表中,但我遇到了

System.ObjectDisposedException: 'Cannot access a disposed object. Object name: 'uEligibilityCondition'.

的错误

代码如下:


private void SaveSessionConditions()
{
    for (int i = 0; i < tableLayoutPanelConditions.RowCount - 1; i++)
    {
        uCustomControl custom = 
            tableLayoutPanelConditions.GetControlFromPosition(0, i) as uCustomControl;

        parent.sessionConditions.Add(control);
    }
}

private void CallSessionConditions()
{           

    foreach (uCustomControl custom in parent.conditions)
    {       
        int row = tableLayoutPanelConditions.RowCount - 1;
        
        // the line with the error 
        tableLayoutPanelConditions.Controls.Add(custom, 0, row);


        tableLayoutPanelConditions.RowCount = tableLayoutPanelConditions.RowCount + 1;
        tableLayoutPanelConditions.RowStyles.Add(new RowStyle(SizeType.Absolute, 40F));
    }
}

代码的第一次迭代我有一个用于保存的按钮,另一个用于删除所有条件的按钮,以及另一个加载按钮。这有效。组合框选择和文本框值被正确存储并调用到子窗体的空 TableControlPanel 中。

但是,一旦我开始实现它,就像保存按钮在保存后关闭子表单一样,然后在打开新的子表单时,它会显示我提到的错误。

为了修复它,我通过创建 uCustomControl 的新实例来修改代码。

private void CallSessionConditions()
{           
    // I tried one with parent.conditions and one with a conditions list within the form itself

    foreach (uCustomControl custom in conditions)
    {

        uCustomControl newCustom = new uCustomControl();

        newCustom.comA = custom.comA;
        newCustom.comB = custom.comB;
        newCustom.texA = custom.texA;
        newCustom.texB = custom.texB;


        int row = tableLayoutPanelConditions.RowCount - 1;
        
        tableLayoutPanelConditions.Controls.Add(newCustom, 0, row);



        tableLayoutPanelConditions.RowCount = tableLayoutPanelConditions.RowCount + 1;
        tableLayoutPanelConditions.RowStyles.Add(new RowStyle(SizeType.Absolute, 40F));
    }
}

因此,在此之后,控件/行的数量是正确的。但是,ComboBox 选定的项目和 TextBox 文本都不正确。它们要么默认为第一项,要么有一个空文本字段。我还检查了父级和子级中的列表,父级和子级中的列表都保存了组合框,但没有保存文本框值,即使如此,组合框选择也没有分配给 newCustom。

为了进一步澄清,下面是uCustomControl中的getter和setter

public string comA
{
    get { return comboBoxA.SelectedItem.ToString(); }
    set { comboBoxA.SelectedItem = value; }
}

public string comB
{
    get { return comB.SelectedItem.ToString(); }
    set { comboBoxB.SelectedItem = value; }
}

public string texA
{
    get { return textBoxA.Text; }
    set { textBoxA.Text = value; }
}

public string texB
{
    get { return textBoxB.Text; }
    set { textBoxB.Text = value; }
}


我进一步的想法包括制作一个自定义方法,该方法接受一个控件并使用它来分配正确的值,但到目前为止我还停留在它的实现上,因为我也不太明白我目前面临的问题以及原因它发生了,我想在这里问一下,以便我更好地理解我的代码。

感谢您花时间阅读。

更新:我尝试了一个解决方案并在下面制作了一个自定义方法:

public void SetFromControlInput(uEligibilityCondition input)
{
    comboBoxA.SelectedItem = input.comboBoxA.SelectedItem;
    comboBoxB.SelectedItem = input.comboBoxB.SelectedItem;
    textBoxA.Text = input.textBoxA.Text;
    textBoxB.Text = input.textBoxB.Text;
}


并使用它而不是逐一分配每个属性

newCustom.SetFromControlInput(custom);

它有点有效并解决了组合框未保存的问题,因为现在看来 newCustom 确实反映了组合框选择,但问题仍然是文本框为空,并且也无法保存到之前的列表中。

c# winforms user-controls getter-setter
1个回答
0
投票

我设法找到了答案。我不知道这是否是最佳实践,但它符合我的预期。对代码的唯一调整如下:

private void SaveSessionConditions()
{
    for (int i = 0; i < tableLayoutPanelConditions.RowCount - 1; i++)
    {
        uCustomControl custom = 
            tableLayoutPanelConditions.GetControlFromPosition(0, i) as uCustomControl;

        // new code below

        uCustomControl newCustom = new uCustomControl();
        newCustom.SetFromControlInput(custom);

        parent.sessionConditions.Add(newCustom);
    }
}

我意识到我的第一次编辑允许我解决无法访问已处置对象的错误,唯一的问题是值设置不正确,我决定创建一个新的控件实例并在之前单独设置值节省。

所以现在,只要父窗体打开,我的应用程序就可以保留会话控件的值,并将它们添加到新的子窗体中。

© www.soinside.com 2019 - 2024. All rights reserved.