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);
                                }
                            }

                    });
            });
    }

ExecuteSecureのコードは次のとおりです

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

基本的に、私は固定サイズのフォームとフォーム上のいくつかのグループボックスを持っていますが、どの時点でもそのうちの1つだけが表示されます。新しいGroupBoxを表示する必要がある場合は、DoSlide(GroupBox)を呼び出して、表示するグループボックスを指定します。次に、スライド(インクリメントまたはデクリメントされたbox.left)を表示する指定されたフォームを除いて、フォーム上のすべてのGroupBoxを場所(-Box.Width、27)に移動することになっています。

4

4 に答える 4

11

使いたい

this.Controls.OfType<GroupBox>()

あなたのforeachで。This.Controlsは、GroupBoxだけでなく、すべてのコントロールを返します。拡張メソッドはOfType<T>、指定したタイプにコレクションをフィルタリングします。

于 2012-11-27T20:36:11.067 に答える
4

各コントロールをループするときは、コントロールがすべてGroupBoxオブジェクトであると想定するだけでなく、コントロールのタイプを決定する必要があります。

于 2012-11-27T20:36:47.890 に答える
2

this.Controlsコレクションには、フォームの第1レベルのコントロールがすべて含まれているため、内部のすべてのコントロールがGroupBoxであるとは限りません。GroupBoxコントロールのみを取得する必要があります

この構文を使用してループを変更します

foreach (GroupBox box in this.Controls.OfType<GroupBox>())
{
   ....
}
于 2012-11-27T20:37:35.370 に答える
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 に答える