AvailableItemAttribute - How to pass a collection of items?

Last post 09-02-2008 6:00 PM by exsurgo. 4 replies.

Sort Posts:

  • AvailableItemAttribute - How to pass a collection of items?

    08-29-2008, 2:19 AM
    • Member
      point Member
    • exsurgo
    • Member since 09-07-2007, 12:42 AM
    • Posts 22

    I would like to create a new attribute which both populates the ListItems of controls such as the DropDownList and ListBox, and also validates that the data returned is a value within the collection.   The source of the collection might come from several possible sources such as a collection property, a Dictionary or a NameValueCollection.

    Unfortunately, as I've learned, you cannot pass an object as a parameter to attributes.    I've considered the following:

    1) Pass a delimited string:   <AvailableItems("Red=1|Blue=2|Green=3")> _   ...  This works, but seems very clumsy.

    2) Pass a Enumerator:  <AvailableItems(ColorType)> _ ...  The problem here is that's not very display friendly, and there can be no Text/Value pairing.

    3) Pass a property name and use reflection to retrieve the object:   <AvailableItems("MyClass.MyColorProperty")> _  ... Not sure how well this would work.

    4) Pass the name of a Cache or Application key:  <AvailableItems("MyCacheKey")> _ ... This might work well

    Is there a better way that I haven't thought of?  Is there any way to pass an object as a attribute parameter?

     Also, how would you validate that the data returned is one of the items?

  • Re: AvailableItemAttribute - How to pass a collection of items?

    08-29-2008, 10:37 AM
    • Member
      82 point Member
    • Adult
    • Member since 08-26-2008, 2:29 AM
    • Posts 44

     Why just dont return dictionary or NameValue as property??? Then you can create your custom field?

    Also,if you want to pass Enum with description,you can put attributes like Description("test") on Enum values.

  • Re: AvailableItemAttribute - How to pass a collection of items?

    08-29-2008, 5:02 PM
    • Member
      point Member
    • exsurgo
    • Member since 09-07-2007, 12:42 AM
    • Posts 22

    That's actually what I'm trying to do, but unless I'm missing something, you can't pass a dictionary as a parameter to an attribute.   It give the error, "constant expression is required".    You can't pass the dictionary through the constuctor nor to a field or property.  

    That would be perfect if we could, as all of our lookup data comes from dictionarys or key/value type collections.    I think that we've already dismissed the possibility of using an enum, because you can't have a name and a value if they're both strings, and the name cannot have spaces or special characters.

     At this point, I'm thinking that the best option might be to pass in a property name as a string, and use reflection to call it...

    <AvailableItems("LookupData.StatusCodes")>_

    then use reflection so call the property and retrieve the dictionary, assuming that 'LookupData' is the static class, and StatusCodes is a property that returns a dictionary.

    Any other ideas would be appreciated.

  • Re: AvailableItemAttribute - How to pass a collection of items?

    08-30-2008, 4:27 PM
    • Star
      12,346 point Star
    • sjnaughton
    • Member since 04-29-2008, 5:11 PM
    • Newton-le-Willows, Merseyside, UK
    • Posts 2,571
    • TrustedFriends-MVPs

    Try this, I know its in c# but you should be able to work it out Smile 

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
    public class TablePermissionsAttribute : System.Attribute
    {
    	// this property is required to work with "AllowMultiple = true" ref David Ebbo
    	// As implemented, this identifier is merely the Type of the attribute. However, 
    	// it is intended that the unique identifier be used to identify two 
    	// attributes of the same type.
    	public override object TypeId { get { return this; } }
    
    	/// <summary>
    	/// Constructor
    	/// </summary>
    	/// <param name="permission"></param>
    	/// <param name="roles"></param>
    	public TablePermissionsAttribute(Permissions permission, params String[] roles)
    	{
    		this._permission = permission;
    		this._roles = roles;
    	}
    
    	private String[] _roles;
    	public String[] Roles
    	{
    		get { return this._roles; }
    		set { this._roles = value; }
    	}
    
    	private Permissions _permission;
    	public Permissions Permission
    	{
    		get { return this._permission; }
    		set { this._permission = value; }
    	}

     in c# we would use the params key word to set this up, see the vb that a c#->vb converter did:

     

    Public Sub New(ByVal permission As Permissions, ParamArray roles As String()) 
        Me._permission = permission 
        Me._roles = roles 
    End Sub 
     

     

    Hope this helps Big Smile
    Steve Big Smile

    Always seeking an elegant solution.
    [Oh! If olny I colud tpye!]
    c# Bits blog
    Oh, and don't forget to mark as answer any posts that help you Big Smile
    Filed under: ,
  • Re: AvailableItemAttribute - How to pass a collection of items?

    09-02-2008, 6:00 PM
    • Member
      point Member
    • exsurgo
    • Member since 09-07-2007, 12:42 AM
    • Posts 22

    Thanks for this suggestion.  Using the ParamArray is not somthing we had considered.  

     Though this will help in some cases where the array is a small, static set of items, we still need a way that large sets of items can be passed in a dynamic way.   After much research, I've concluded that there is no way to pass an object like an array or dictionary to a parameter, unless the attribute declaration contains the expression.

     For the time being, we've settled on using a delimited parameter string, ex:  <AvailableItems("Red=R|Blue=B|Green=G")> ... that way a property could still be called that dynamically created the string, ex:  <AvailableItems(LookupData.ColorsString)>

     

Page 1 of 1 (5 items)