I have this custom attribute - that defines some values I could use in PropertyGrid to build list of valid values that user can pick from when editing property value, but is not limited to this:
[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
sealed class ValidValuesAttribute : Attribute
{
readonly string[] _validValues;
public ValidValuesAttribute(params string[] values)
{
this._validValues = values;
}
public string[] ValidValues
{
get { return _validValues; }
}
}
When I use this in "design" time, it works perfectly:
[DefaultValue("A1")]
[Editor(typeof(DropSelectEditor), typeof(UITypeEditor))]
[ValidValues(new string[] {"A1", "B2", "C$" })]
public string ConnectedState { get; set; }
It also worked well when i tried with "params" constructor.
Then I'm building this property in runtime, using CustomAttributeBuilder. All of it looks to work fine:
private CustomAttributeBuilder GetAttributeBuilder_ValidValuesAttribute(PropertyDefinition tProperty)
{
string[] values = (string[]) tProperty.PropertyMetadata.AllowedValues.ToArray().Clone();
if (values.Length > 0)
{
Type[] ctorParams = new Type[] { typeof(string[]) };
ConstructorInfo classCtorInfo = typeof(ValidValuesAttribute).GetConstructor(ctorParams);
CustomAttributeBuilder builder = new CustomAttributeBuilder(classCtorInfo, new object[] { values });
return builder;
}
else
return null;
}
and is also fine, when I'm passing it to PropertyBuilder:
builder = GetAttributeBuilder_ValidValuesAttribute(propertyMeta);
if (builder != null)
myPropertyBuilder.SetCustomAttribute(builder);
Even in Debug, I can see that there is data blob in builder that contains what I'd just set in the constructing function.
(There is list of other attributes that are being added at this time - EditorAttribute, DefaultValueAttribute etc. All of them work just fine.)
Then I just create instance of this type:
object obj = Activator.CreateInstance(t);
But when I try to enumerate attributes on one of those dynamic roperties, I find all attributes (including other custom ones) except this one. Like that:
foreach (PropertyInfo propInfo in obj.GetType().GetProperties())
{
foreach (object att in propInfo.GetCustomAttributes(false))
{
}
}
So, before I redesign a bit my classes to read these array from metada that I will attach to the object (It's fine from design point but not the way the PropertyGrid is intended to be used in general), I would like to know:
1. Did I made any mistake? Ommited something crucial?
2. Or there is just error?
3. Or maybe I shall use other activator than that simple one
Just for a quick note - It seems, that I'd created everything else well, type and object are created without any errors, other attributes exist and work correctly, and objects with properties are being rendered in PropertyGrid properly.
I've been looking for some code like this, but it only seems that array of string is a valid type to be used with Attribute. Did not found a person that had such problem, but also no one that tried doing this.
Thank you in advance for any clues.
Sebastian