通过反思获得控制权

时间:2011-05-14 12:26:08

标签: c# .net reflection

我需要通过使用反射的ID来从我的页面获取控件[文本框,标签,按钮...等]

在我的情况下,我有一个类,所有其他系统页面都从它继承,这个类重写onload事件,将一些属性更改为某些控件

喜欢设置文本框的可见性状态,但由于我没有直接在页面上的控件,因为我可能在主页面中的内容占位符上有它所以我不能使用findcontrol方法我也认为递归找到控件的功能会花费太多时间

所以我尝试用refelection来查找名称为的控件然后更改它的可见或启用状态

我使用了FieldInfo类,但不能和我一起使用

FieldInfo fi = this.GetType().GetField("ControlID", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase);

任何帮助!

3 个答案:

答案 0 :(得分:7)

您是否尝试过FindControl

  Control myControl = this.FindControl("TextBox2");
  if(myControl !=null)
  {
       // Do Stuff
  }

答案 1 :(得分:1)

也许您需要递归使用FindControl查找控件,然后自行调用?

private static Control FindNestedControl(string id, Control parent)
{
    Control item = parent.FindControl(id);

    if(item == null) 
    {
        foreach(var child in parent.Controls)
        {
            item = child.FindNestedControl(id, child);

            if(item != null)
            {
                return item;
            }
        }
    }

    return null;
}

并通过以下方式调用它传递页面的当前实例:

Control item = FindNestedControl("bob", this);

但这可能会很慢 - 所以如果页面上有一大堆控件,请注意这一点:)

另一种方法是将控件公开为基类中的属性:

public abstract class BasePage : Page
{
    #region Properties

    /// Gets the textbox for editing in derived classes.
    protected TextBox SomeTextBox
    {
       return this.textBox; }
    }

    #endregion

}

最后一种方法是挂钩基类中的派生类:

public abstract class BasePage : Page
{
        /// <summary>
        /// Called when loading the page.
        /// </summary>
        /// <param name="e">The event arguments.</param>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            // Do some basic setup.

            // Now pass the controls to the derived classes.
            this.ConfigureControl(this.mainText);
            this.ConfigureControl(this.nameDropDown);
            this.ConfigureControl(this.someOtherControl);            
        }

        /// <summary>
        /// Provides hook for derived classes.
        /// </summary>
        /// <param name="control">The core control.</param>
        protected virtual void ConfigureControl(Control control)
        {
        }
 }

然后在您的派生页面中覆盖:

protected override void ConfigureControl(Control control)
{
    switch(control.ID) 
    {
        case "mainText":
        TextBox mainText = (TextBox)control;
        mainText.Text = "works";
        break;
    }
}

如果没有那么多控件,我可能会使用第二个。在处理转发器等时,第一种方法很有用。

答案 2 :(得分:0)

这是递归获取子控件的非常有用的扩展方法:

public static IEnumerable<Control> GetChildControls(this Control control)
{
    var children = (control.Controls != null) ? control.Controls.OfType<Control>() : Enumerable.Empty<Control>();
    return children.SelectMany(c => GetChildControls(c)).Concat(children);
}

用法:

IEnumerable<Control> allChildren = parent.GetChildControls();