【问题标题】:How is this throwing an InvalidCastException这是如何抛出 InvalidCastException
【发布时间】:2012-11-27 20:33:12
【问题描述】:

以下代码片段在 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)进入视图。

【问题讨论】:

  • 你能发布一个堆栈跟踪吗?
  • this.Controls 中的所有项目都是 GroupBox 类型(或其子类)吗?

标签: c# .net anonymous-methods


【解决方案1】:

你想用

this.Controls.OfType<GroupBox>()

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

【讨论】:

  • 基本上this.Controls包含的不仅仅是GroupBoxes,所以你只需要指定groupboxes
  • 宾果游戏,我们在 another question 中遇到了同样的问题,而不是 4 小时前。 :)
  • 我不能足够快地接受答案! - 非常感谢您的快速回复。不到 2 分钟就解决了这个问题。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    使用此语法更改循环

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

    【讨论】:

      【解决方案4】:

      并非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,这样可能会产生更好的性能...

      【讨论】:

      • 我怀疑其他代码是否更快。 OfType&lt;GroupBox&gt;() 必须检查每个项目是否也是 GroupBox
      猜你喜欢
      • 2020-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-17
      相关资源
      最近更新 更多