|
■No47460 (msnr さん) に返信
> 今後、foreach内でネストが深くなるのを避けたいと思っております。
そもそも、毎回、Controls から列挙しようとするのではなく、
ループで操作しやすいよう、事前に Load イベントの時点で
private List<TextBox> textBoxes;
などに蓄えておく事をおすすめします。
その方が、今後、TextBox の名前が変更された場合にも有利ですし、あるいは
「TextBox1,3,4」と「TextBox2,5,7」を分けて管理したいといった場合でも、
都合が良いと思います。
> foreach (Control t in c.Controls)
t.Controls も含めて、再帰的に探索しなくても大丈夫でしょうか?
今のコードは、指定されたコントロールの直下にある物しか見ていないので、
Form1
├panel1
│├textBox1
│├panel2
││└textBox2
│└textBox3
└textBox4
のような構造の時に『checkTextBox(panel1)』を行うと、
textBox1, textBox3 は得られますが、textBox2 は操作されません。
> foreach (Control t in c.Controls)
> {
> do
> {
> if (!(t is TextBoxBase)) { break; } ←ここの書き方も不安です・・・
> if (t.Name.ToString() == "textBox4") { break; }
> if (t.Text == null || t.Text.Length == 0)
> {
> MessageBox.Show(t.Name);
> break;
> }
> } while (true);
> }
そのコードだと、3 つの break 条件いずれにもヒットしなかった場合、
無限ループに陥ってしまいますよ。
> ←ここの書き方も不安です・・・
内側のループは不要だと思います。TextBox のみを対象としたいなら、
foreach (Control t in c.Controls)
{
if(!(t is TextBoxBase)) continue;
:
}
とすればよいかと。
また、C# 2008 以降であれば if 判定も不要で、
foreach (TextBoxBase t in c.Controls.OfType<TextBoxBase>())
{
:
}
で済ます事もできます。
> if (t.Text == null || t.Text.Length == 0)
前者の条件は、あまり意味が無いと思います。
TextBox の場合、Text プロパティが null を返すことはなく、
null をセットしても "" として扱われる仕様になっていますので、
この場合には、
if( string.IsNullOrEmpty(t.Text) )
でどうでしょうか。
あるいは、Control.Text.Length で取得する代わりに、
TextBoxBase.TextLength プロパティを使うという手もあります。
|