7

Text プロパティにアクセスしようとする代わりに、フォームのさまざまなコントロールを反復処理すると、次のようになります。

String text = String.Empty;
foreach(Control control in this.Controls)
{
   try
   {
      text = control.Text;
   }
   catch(Exception exception)
   {
      // This control probably doesn't have the Text property.
      Debug.WriteLine(exception.Message);
   }
}

特定のコントロールにText プロパティがあるかどうかを判断する方法はありますか? このようなもの:

String text = String.Empty;
foreach(Control control in this.Controls)
{
   if(control has Text property)
   {
      text = control.Text;
   }
}

私は Try/Catch ブロックを絶対に軽蔑します (もちろん、より良い代替手段がない場合を除きます)。

4

3 に答える 3

8

すべてのControlオブジェクトにはTextプロパティがあるため、リフレクションを使用してそれを決定しても意味がありません。常に返されtrueます。

実際の問題は、一部のコントロールがTextサポートしていないため、プロパティから例外をスローすることです。

事前にわからないカスタム コントロールも使用できるようにする場合は、現在のソリューションに固執し、例外をキャッチする必要があります。ただし、たとえば、スローされた特定の例外をキャッチする必要がありますNotSupportedException

事前にわかっているコントロールしか見つからない場合は、機能するプロパティがあることがわかっているコントロールを選択できますText。例えば:

public static bool HasWorkingTextProperty(Control control)
{
    return control is Label
        || control is TextBox
        || control is ComboBox;
}

var controlsWithText = from c in this.Controls
                       where HasWorkingTextProperty(c)
                       select c;

foreach(var control in controlsWithText)
{
    string text = control.Text;
    // Do something with it.
}

また、プロパティを持つ場合と持たない場合がある独自のカスタム コントロールを実装する場合はText、次のことを示す基本クラスからそれらを派生させることができます。

public abstract class CustomControlBase : Control
{
    public virtual bool HasText
    {
        get { return false; }
    }
}

public class MyCustomControl : CustomControlBase
{
    public override bool HasText
    {
        get { return true; }
    }

    public override string Text
    {
        get { /* Do something. */ }
        set { /* Do something. */ }
    }
}

public static bool HasWorkingTextProperty(Control control)
{
    return (control is CustomControlBase && ((CustomControlBase)control).HasText)
        || control is Label
        || control is TextBox
        || control is ComboBox;
}
于 2013-03-06T00:06:52.253 に答える
5

あなたの質問は、コントロールが Text プロパティを持っているかどうかを判断する方法です。したがって、リフレクションを使用してそれを行う方法は次のとおりです。

control.GetType().GetProperties().Any(x => x.Name == "Text");

編集:Controlクラスを見ると、プロパティがあることがわかりTextます。

現在、クラスをオーバーライドするカスタム コントロールがプロパティControlにアクセスするときに例外をスローする場合、それはLiskov 置換原則に違反しています。その場合は、それらのコントロールを特定することをお勧めしますが、あなたがしていることは問題ないようです。Text

于 2013-03-06T00:02:10.320 に答える
3

これをチェックしてください:

private void Form1_Load(object sender, EventArgs e)
{
     foreach (Control ctrl in this.Controls)
     {
          PropertyInfo[] properties = ctrl.GetType().GetProperties();
          foreach(PropertyInfo pi in properties)
              if (pi.Name == "Text")
              { 
                    //has text
              }
       }

}
于 2013-03-06T00:00:29.120 に答える