这是怎么抛出InvalidCastException的

时间:2012-11-27 20:33:13

标签: c# .net anonymous-methods

以下代码片段在foreach循环上抛出InvalidCastException:

  

无法将'System.Windows.Forms.StatusStrip'类型的对象强制转换为   输入'System.Windows.Forms.GroupBox'。

我只是不明白这是怎么可能的...... 然后我又是一个菜鸟,所以它可能是一个愚蠢的东西。

     private void doSlide(GroupBox MoveThis)
    {
        //location 12,27
        var t = Task.Factory.StartNew(() =>
            {
                ExecuteSecure(() =>
                    {
                            foreach (GroupBox box in this.Controls)
                            {
                                if (box != MoveThis)
                                {
                                    box.Left = (-1) * box.Width;
                                }
                                else
                                {
                                    do
                                    {
                                        if (box.Left > 12)
                                            box.Left--;
                                        else
                                            box.Left++;
                                    }
                                    while (box.Left != 12);
                                }
                            }

                    });
            });
    }

以下是执行安全的代码

private void ExecuteSecure(Action a)
        {
            if (InvokeRequired)
                BeginInvoke(a);
            else a();
        }

基本上我有一个固定大小的表单和表单上的几个组框,其中只有一个在任何给定点都可见。当我们需要创建一个新的GroupBox时,我们调用DoSlide(GroupBox)并指定我们想要显示的组框。然后它应该将窗体上的每个GroupBox移动到位置(-Box.Width,27),除了指定的窗体(滑块(递增或递减的box.left))进入视图。

4 个答案:

答案 0 :(得分:11)

您想要使用

this.Controls.OfType<GroupBox>()
在你的foreach中。 This.Controls返回所有控件,而不仅仅是GroupBoxes。 OfType<T>扩展方法将集合过滤为您指定的类型。

答案 1 :(得分:4)

当你循环遍历每个控件时,你应该确定控件的类型而不只是假设它们都是GroupBox对象

答案 2 :(得分:2)

this.Controls集合包含所有表单的第一级控件,因此并非每个控件都是GroupBox。您只需要获得GroupBox控件

使用此语法更改循环

foreach (GroupBox box in this.Controls.OfType<GroupBox>())
{
   ....
}

答案 3 :(得分:2)

并非Controls集合中的每个控件都是GroupBox(显然),但foreach正试图将它们内联投射。

所以,把你的循环改成这样的东西:

foreach (var control in this.Controls)
{
    if(control is GroupBox)
    {
        if (control != MoveThis)
        {
            control.Left = (-1) * control.Width;
        }
        else
        {
            do
            {
                if (control.Left > 12)
                    control.Left--;
                else
                    control.Left++;
            }
            while (control.Left != 12);
        }
    }
}

编辑:值得注意的是,这可能会非常慢,因为您正在评估表单中每个控件的类型。 John Kraft和Steve建议的代码应该将控件集合过滤到那些GroupBox的代码,这样可能会产生更好的性能...