Click here to Skip to main content
15,904,416 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
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:

C#
/// <summary>
    /// Apply list of valid known values for specific property
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
    sealed class ValidValuesAttribute : Attribute
    {
        readonly string[] _validValues;

        public ValidValuesAttribute(params string[] values)
        {
            this._validValues = values;
        }

        /// <summary>
        /// List of well-known values
        /// </summary>
        public string[] ValidValues
        {
            get { return _validValues; }
        }
    }


When I use this in "design" time, it works perfectly:

C#
[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:

C#
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:

C#
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:

C#
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:

C#
foreach (PropertyInfo propInfo in obj.GetType().GetProperties())
            {
                foreach (object att in propInfo.GetCustomAttributes(false))
                {
                    // There were no droid I've been looking for!
                }
            }


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
Posted
Updated 29-Nov-11 0:34am
v2

1 solution

Hello Sebastian,

Why going over attributes? I get the impression that you "abuse" the attribjtes for something you could do straight forward without attributes. Maybe I'm wrong.

You seem to load the meta data at runtime, so, use a common data structure that you populate and pass to your PropertyGrid at runtime - not attributes.

My view of attributes is something for declaring at compile time and accessing via reflection.

Probably most of the developers view it like this - no wonder that you hardly find anyone doing what you're trying to do.

Cheers

Andi
 
Share this answer
 
Comments
BillWoodruff 6-Feb-12 18:54pm    
Andreas, I have real "empathy" for the type of question that Sebastian is raising here, because I haven't seen, since the book I mentioned to you previously, a really thorough walk-through article on creating custom controls with sophisticated PropertyGrid custom selection/editor interfaces.

I'm hoping you might be the CP author: to write a great article on this ! :)

best, Bill

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900