1

我得到一个StackOverflowException. 不知何故,在这里发帖似乎很合适。

我在 C# 应用程序中使用 Windows 窗体。这个应用程序打算在Linux、FreeBSD和Mac-OS上运行,所以我不能使用WPF,所以请不要推荐它。

我的猜测是我错过了 WinForms 的细微差别,但我似乎无法弄清楚是什么。

由 VS 2010 中的ComboBoxGUI 表单生成器生成。

抛出错误的特定代码行在这里:

if(cur_num_is_valid)
{
    cbx_material_num.Text = num;
}
else
{
    num = "0";
    //I only have one of the following two at a time. Both overflow
    cbx_material_num.SelectedIndex = 0;
    cbx_material_num.Text = "0";
}

由于代码有些复杂,这里是整个函数代码。'cbx_' 表示组合框。'txtb_' 是一个文本框。

private void cbx_material_numobj_SelectedIndexChanged(object sender, EventArgs e)
{
    string obj = cbx_material_obj.Text;
    string num = cbx_material_num.Text;
    int selnum = 0;
    int n = 0;

    //do we need to recreate the numbers array?
    bool cur_num_is_valid = false;
    cbx_material_num.Items.Clear();
    if(obj != lastobj)
    {
        n = m_demo.get_object_modifiers(obj);
        for(int i = 0; i <= n; i++)
        {
            string s = i.ToString();
            if(s == num && i < n) cur_num_is_valid = true;
            cbx_material_num.Items.Add(s);
        }
    }
    if(cur_num_is_valid)
    {
        cbx_material_num.Text = num;
    }
    else
    {
        num = "0";
        //Overflow here:
        cbx_material_num.SelectedIndex = 0;
    }

    try
    {
        selnum = int.Parse(num);
    }
    catch(Exception)
    {
        MessageBox.Show("Error, second select menu after 'object modifiers' must be a number, not '"+num+"'.");
        cbx_material_num.Text="0";
        return;
    }

    if(selnum >= n)
    {
        txtb_material_param1.Text = "0";
        txtb_material_param2.Text = "0";
        txtb_material_param3.Text = "0";
        txtb_material_param4.Text = "0";
    }
    else
    {
        MaterialFace face;
        MaterialParameter parameter;
        int typeid;
        object paramdata;
        m_demo.get_object_modifiers_material(obj, selnum, out face, out parameter, out typeid, out paramdata);
        cbx_material_face.Text = face.ToString();
        cbx_material_paramtype.Text = parameter.ToString();
        switch(typeid)
        {
            case 0:
                txtb_material_param1.Text = ((float)paramdata).ToString();
                cbx_material_datatype.Text = "float";
                goto case -1;
            case 1:
                float[] parsf = ((float[])paramdata);
                txtb_material_param1.Text = parsf[0].ToString();
                txtb_material_param2.Text = parsf[1].ToString();
                txtb_material_param3.Text = parsf[2].ToString();
                txtb_material_param4.Text = parsf[3].ToString();
                cbx_material_datatype.Text = "float[]";
                break;
            case 2:
                txtb_material_param1.Text = ((int)paramdata).ToString();
                cbx_material_datatype.Text = "int";
                goto case -1;
            case 3:
                int[] parsi = ((int[])paramdata);
                txtb_material_param1.Text = parsi[0].ToString();
                txtb_material_param2.Text = parsi[1].ToString();
                txtb_material_param3.Text = parsi[2].ToString();
                txtb_material_param4.Text = parsi[3].ToString();
                cbx_material_datatype.Text = "int[]";
                break;
            case -1: //can't actuall be returned, used to 'blank' the last three as '0'
                txtb_material_param2.Text = "0";
                txtb_material_param2.Text = "0";
                txtb_material_param3.Text = "0";
                break;
            case 4:
                OpenTK.Graphics.Color4 paramc = ((OpenTK.Graphics.Color4)paramdata);
                txtb_material_param1.Text = paramc.R.ToString();
                txtb_material_param2.Text = paramc.G.ToString();
                txtb_material_param3.Text = paramc.B.ToString();
                txtb_material_param4.Text = paramc.A.ToString();
                cbx_material_datatype.Text = "Color4";
                break;
            default: //5
                Vector4 paramv = ((Vector4)paramdata);
                txtb_material_param1.Text = paramv.X.ToString();
                txtb_material_param2.Text = paramv.Y.ToString();
                txtb_material_param3.Text = paramv.Z.ToString();
                txtb_material_param4.Text = paramv.W.ToString();
                cbx_material_datatype.Text = "Vector4";
                break;
        }
    }
}
4

2 回答 2

2

在尝试设置 SelectedIndex 之前,您需要检查它是否已经为 0:

    if (cbx_material_num.SelectedIndex != 0){
       cbx_material_num.SelectedIndex = 0;
    }

否则,您每次都会重新触发该事件。

于 2012-10-26T01:00:19.960 回答
0

我认为,每当您cbx_material_num.SelectedIndex = 0;在其中设置它时,EventHandler您都会调用您的

cbx_material_numobj_SelectedIndexChanged(object sender, EventArgs e)

每次调用都会调用另一个事件处理程序,因此堆栈会在一段时间后填满。基本上,它被称为 SelectedIndexChanged 的​​事实并不意味着该值必须与前一个不同,而是该值是通过其设置器设置的。

于 2012-10-26T00:37:48.597 回答