2010-12-24 18 views
1

TextBoxコントロールがフォームのControlsプロパティに追加される順序に特有の問題があります。foreach(Control ctrl in Frm.Controls)コントロールの順番

現在、私は機能を持っている:

public static bool IsValidate(System.Windows.Forms.Form Frm) 
{ 
    foreach (Control ctrl in Frm.Controls)     
     if (ctrl is TextBox) 
     // if (((TextBox)ctrl).AccessibleDescription == "Valid" && ((TextBox)ctrl).Text == string.Empty) 
     if (((TextBox)ctrl).AccessibleDescription == "Valid" && ((TextBox)ctrl).Text.Trim()== "") 
     { 
      MessageBox.Show(((TextBox)ctrl).AccessibleName + " Can't be Blank", Program.companyName, MessageBoxButtons.OK, MessageBoxIcon.Stop);       
      ((TextBox)ctrl).Focus(); 
       return false; 
     } 
     return true; 
} 

しかし、私が彼らのタブインデックスを設定しているにもかかわらず、ランダムにテキストボックスを反復処理です。

私は再び同じフォームを開発し、テキストボックスを順番に作成します。しかし、私はこの関数にフォームを渡すと、テキストボックスをランダムに反復しています。

フローの管理を可能にするコントロールのプロパティがあるかどうかを知りたいと思います。

答えて

4

Controlsコレクションでは、コントロールを手動で並べ替えるほうがずっと簡単です。例(TabOrderによる種類):

private static int CompareTabIndex(TextBox c1, TextBox c2) 
    { 
     return c1.TabIndex.CompareTo(c2.TabIndex); 
    } 

    public static bool IsValid(Form form) 
    { 
     List<TextBox> textBoxes = new List<TextBox>(); 
     foreach(Control ctl in form.Controls) 
     { 
      TextBox textBox = ctl as TextBox; 
      if(textBox != null) textBoxes.Add(textBox); 
     } 
     textBoxes.Sort(new Comparison<TextBox>(CompareTabIndex)); 
     foreach(TextBox textBox in textBoxes) 
     { 
      if(textBox.AccessibleDescription == "Valid" && textBox.Text.Trim() == "") 
      { 
       MessageBox.Show(textBox.AccessibleName + " Can't be Blank", 
        Program.companyName, MessageBoxButtons.OK, MessageBoxIcon.Stop); 
       textBox.Focus(); 
       return false; 
      } 
     } 
     return true; 
    } 
+0

thaxその作業......... –

+1

もちろん、2つのコントロールが同じ 'TabOrder'を持つことができます。そして、コントロールが複数のコンテナ( 'Panel'や' TableLayoutPanel'のような)にある場合、これはさらに複雑になり始めます。 –

3

実際にコントロールを「ランダムに」反復処理していますか? (それは非決定論的であり、その順序は毎回変わる可能性があることを暗示する)、あるいはそれは毎回同じ順序でコントロールを反復していますが、あなたが期待する順序ではありませんか? C#言語仕様explicitly states the ordering of foreach(最初の答えを参照)が与えられていることを前提に、私はそれが後者であると思われます。

タブの順序は、コントロールの順序には影響しません。それはちょうどUIの目的のためです。バッキングストアの配列要素としてのコントロールの実際の順序は、フォームを作成するときに作成された順序によって制御される可能性が高くなります。

フォームをもう一度開発し、「テキストボックスを順番に使用する」最後の部分についてさらに詳しく説明できますか?

+0

オーダーは同じです... –

+0

@Sheetal Inani:それからランダムではありません。私は、注文はコントロールがフォーム上に作成された順序であると考えています。 @maxはこの問題に興味深いアプローチをしました。私は内部的にそれが建築的な観点からどこに属するのかを議論していますが、掲載されているように、おそらくあなたが必要とするものを達成するための最短経路になるでしょう。 – David

+0

これは "give me teh codez"サイトだったのですか?プログラムに入るコードをコピーして貼り付けるだけです。あなたのデザインが最も適切でないかもしれないという事実は無関係です。 –

0

あなたが視覚的にデザイナでフォームにコントロールをドロップした後、Form.Designer.csソースファイルを開き、設計者がにコードで入力した場所を特定することができますControlsコレクション(Controls.Add行)にコントロールを追加し、* .Designer.csの行を手作業で並べ替えます。これを済ませたら、デザイナーはあなたの変更だけを残すべきです。私はデザイナーが逆の順序でそれらを書くことに気づいた。あなたのforeachはあなたがそれらを整理した順序でそれらを見つけるはずです。

2

コントロールは、コントロールのZオーダーの順番に、同じ親コンテナー(最上部から最下部まで)に配置されます。テストするには、フォームにコントロールを配置し、注文を取得します。いくつかのコントロール(設計時または実行時)の場合は、「Send to Back」または「Bring to Front」を適用します。 foreachの順序は、最上位のコントロールを最初と最後に変更します。

生成されたデザイナーコードは、zオーダーに基づいてコントロールを追加します。最も低いコントロールが最初に(最後に一番上のコントロール)。したがって、コンテナに追加される順序に基づいているようです。

BringToFront()とSendToBack()の実装が必要な順序でコントロールを内部的に削除して追加するかどうかはわかりません。私には、zオーダーに基づいてそれを持つことは理にかなっています。上記のように、必要に応じていつでも自分の注文を使うことができます。

+0

親愛なるジオ、あなたの提案は多くの助けになりました。 –

1

私はこの問題を抱えていたと私はDesigner.csに順序制御名を変更し、

this.groupBox3.Controls.Add(this.txtPrice); 
this.groupBox3.Controls.Add(this.txtDate); 
+2

あまりいいことはありません。* .Designer.csファイルを手で編集する予定はありません。 – horgh

+0

これは「覚えやすい」ソリューションです。ありがとう。 –

13

あなたは、その簡単に行うことができます。>その他のWindows - - >ドキュメントアウトライン ビューでフォームのドキュメントアウトラインを参照してください

foreach (Control control in this.Controls.Cast<Control>() 
             .OrderBy(c => c.TabIndex)) 
{ 
} 
-1

フォームであなたのtabindexごとに、次の構文と、ソートのコントロールを使用してください。 必要に応じて、コントロールの階層を変更します。 foreachはそこに見えます