如何通过字符串正确访问UserControl公共属性

时间:2012-02-01 18:25:24

标签: c# asp.net user-controls

我在页面上有一组用户控件,它们根据条件动态加载以运行各种报告(条件驱动程序)。每个控件都有一个或多个公开的属性,用于从我的数据库查询中获取数据。因为每个报告的控件都不同,所以我编写了一个过程来按名称访问相应控件的属性,这样我就可以将它发送到后面代码中的数据库查询(C#)。我得到了所有设置来访问这样的公共财产:

stringVal = userControl.Attributes[stringName].ToString();

它告诉我,我需要新建一个对象。我不明白我需要如何通过字符串名称动态访问该属性。在我眼前的窗口,我可以看到我想要的财产;但是,它不是control.Attributes.Count = 0的“属性”。那么,我如何正确设置它以便我可以通过字符串名称访问它?我需要用某种东西装饰房产吗?

提前谢谢。

2 个答案:

答案 0 :(得分:0)

你需要探索反思。它涉及操纵.NET类型(类,结构,枚举等)的元数据。但是,如果您在具有部分信任的共享主机中运行您的应用程序,则可能无法运行任何类型的反射代码(服务器上的安全限制)。如果是这种情况,请先测试一个小/快的示例(在您的托管上),然后做出相应的决定:是重新设计您的应用还是更改主机。

可能对您有用的与反射相关的代码段(将其粘贴到用户控件类中的某处,如this.GetType()重要:

var properties = this.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);

foreach (var p in properties)
{
    string propertyName = p.Name;
}

还有其他方法可以获得该类型;例如typeof(yourclassname);您还可以反映/获取给定程序集(dll)中的所有类型,等等。

答案 1 :(得分:0)

下面,我编写了一个包装类,您可以使用它来按字符串名称设置/获取包装类的公共字段或属性。

首先,让我们看一下如何在具有公共字段或属性StartDate和SocialSecurityNumber的类上使用它。

// First create the instance we'll want to play with
MyUserControl myControlInstance = new MyUsercontrol();
// MyUserContol has two properties we'll be using
// DateTime StartDate
// int SocialSecurityNumber

// Now we're creating a map to facilitate access to the properties
// of "myControlInstance" using strings
PropertyMap<MyUserControl> map = 
             new PropertyMap<MyUserControl>(myControlInstance);

// Since the map is directed toward "myControlInstance"
// this line is equivalent to:
// myControlInstance.StartDate = Datetime.Now;
map.Set<DateTime>("StartDate", DateTime.Now);

// This line is equivalent to:
// ssn = myUsercontrol.SocialSecurityNumber;
int ssn = map.Get<int>("SocialSecurityNumber");

现在谈谈如何实施:

public class PropertyMap<T>
{
    readonly T Instance;

    public PropertyMap(T instance)
    {
        Instance = instance;
    }

    public U Get<U>(string PropertyName)
    {
        // Search through the type's properties for one with this name
        // Properties are things with get/set accessors
        PropertyInfo property = typeof(T).GetProperty(PropertyName);
        if (property == null)
        {
            // if we couldn't find a property, look for a field.
            // Fields are just member variables, but you can only
            // manipulate public ones like this.
            FieldInfo field = typeof(T).GetField(PropertyName);
            if (field == null)
                throw new Exception("Couldn't find a property/field named " + PropertyName);
            return (U)field.GetValue(Instance);
        }
        return (U)property.GetValue(Instance, null);
    }

    public void Set<U>(string PropertyName, U value)
    {
        // Search through the type's properties for one with this name
        PropertyInfo property = typeof(T).GetProperty(PropertyName);
        if (property == null)
        {
            // if we couldn't find a property, look for a field.
            FieldInfo field = typeof(T).GetField(PropertyName);
            if (field == null)
                throw new Exception("Couldn't find a property/field named " + PropertyName);
            field.SetValue(Instance, value);
            return;
        }
        property.SetValue(Instance, value, null);
    }
}