1

以下代码片段在 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。然后应该将表单上的每个 GroupBox 移动到位置 (-Box.Width,27),但指定的表单除外,它会滑动(递增或递减 box.left)进入视图。

4

4 回答 4

11

你想用

this.Controls.OfType<GroupBox>()

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

于 2012-11-27T20:36:11.067 回答
4

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

于 2012-11-27T20:36:47.890 回答
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,这样可能会产生更好的性能......

于 2012-11-27T20:39:34.533 回答
2

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

使用此语法更改循环

foreach (GroupBox box in this.Controls.OfType<GroupBox>())
{
   ....
}
于 2012-11-27T20:37:35.370 回答