如何确定Control是否具有Text属性

时间:2013-03-05 23:55:14

标签: c# .net winforms xaml

当我在Form上迭代一堆不同的控件时,而不是尝试访问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块(除非当然没有更好的选择)。

3 个答案:

答案 0 :(得分:8)

所有Control个对象都有Text property ,因此使用反射来确定它是没有意义的。它将始终返回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;
}

答案 1 :(得分:5)

您的问题是如何确定Control是否具有Text属性,因此以下是使用Reflection进行此操作的方法:

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

修改:如果您查看Control课程,您会看到它有Text属性。

现在,如果某个覆盖Control类的自定义控件在访问Text属性时会引发异常,则会违反Liskov substitution principle 。在这种情况下,我建议您识别这些控件,尽管您正在做的事情看起来很好。

答案 2 :(得分: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
              }
       }

}