C# winforms/C中更新组合框时出现Stackoverflow异常#

C# winforms/C中更新组合框时出现Stackoverflow异常#,c#,winforms,combobox,stack-overflow,C#,Winforms,Combobox,Stack Overflow,我正在获取一个堆栈溢出异常。不知何故,在这里发帖似乎是合适的 我在C#应用程序中使用Windows窗体。这个应用程序打算在Linux、FreeBSD和Mac操作系统上运行,所以我不能使用WPF,所以请不要推荐它 我的猜测是,我错过了WinForms的一个细微差别,但我似乎不知道是什么 组合框由GUI表单生成器在VS 2010中生成 引发错误的特定代码行如下所示: if(cur_num_is_valid) { cbx_material_num.Text = num; } else {

我正在获取一个
堆栈溢出异常
。不知何故,在这里发帖似乎是合适的

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

我的猜测是,我错过了WinForms的一个细微差别,但我似乎不知道是什么

组合框由GUI表单生成器在VS 2010中生成

引发错误的特定代码行如下所示:

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_ux'表示一个组合框。'txtb_2;是一个文本框

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;
        }
    }
}
private void cbx\u material\u numobj\u SelectedIndexChanged(对象发送方,事件参数e)
{
字符串obj=cbx_material_obj.Text;
字符串num=cbx\u material\u num.Text;
int selnum=0;
int n=0;
//我们需要重新创建数字数组吗?
bool cur_num_是有效的=错误;
cbx_material_num.Items.Clear();
if(obj!=lastobj)
{
n=m_demo.get_object_修饰符(obj);
对于(int i=0;i=n)
{
txtb_material_param1.Text=“0”;
txtb_material_param2.Text=“0”;
txtb_材料参数3.Text=“0”;
txtb_material_param4.Text=“0”;
}
其他的
{
材料表面;
材料参数;
int-typeid;
对象参数数据;
m_demo.get_object_modifiers_material(obj、selnum、out face、out参数、out typeid、out paramdata);
cbx_material_face.Text=face.ToString();
cbx_material_paramtype.Text=参数.ToString();
开关(类型ID)
{
案例0:
txtb_material_param1.Text=((float)paramdata).ToString();
cbx_material_datatype.Text=“float”;
后藤病例1;
案例1:
浮点[]parsf=((浮点[])参数数据);
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[]”;
打破
案例2:
txtb_material_param1.Text=((int)paramdata).ToString();
cbx_material_datatype.Text=“int”;
后藤病例1;
案例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[]”;
打破
case-1://无法实际返回,用于“空白”最后三个,即“0”
txtb_material_param2.Text=“0”;
txtb_material_param2.Text=“0”;
txtb_材料参数3.Text=“0”;
打破
案例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”;
打破
默认值://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”;
打破
}
}
}

我认为,每当您在
EventHandler
中设置此
cbx\u material\u num.SelectedIndex=0;
时,您都会调用

cbx_material_numobj_SelectedIndexChanged(object sender, EventArgs e)
每个调用调用另一个eventHandler,以便堆栈在一段时间后填满。
基本上,它被称为SelectedIndex Changed并不意味着该值必须与前一个不同,而是通过其setter设置该值。

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

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

否则,您每次都会通过触发事件。

如果是这种情况,请改用SelectionChangeCommitted。它仅在用户通过gui更改值时才会触发。有关堆栈溢出的问题请访问meta.stackoverflow.com;;)这不是元问题。StackOverflowException是指堆栈中调用过多。堆栈溢出异常Stackoverflow表示dropdownlist正在重复调用自身
cbx\u material\u numobj\u SelectedIndexChanged
。为避免递归调用,请创建一个名为IsRecursive的私有成员Bool变量,并在调用自身时退出该函数。啊,谢谢。在这种情况下,它几乎肯定总是会这样。