tags:

views:

386

answers:

4

In TagBuilder and other classes I can write something like:

var tr = new TagBuilder("HeaderStyle"){InnerHtml = html, [IDictionary Attributes]}

but I don't know how to pass the IDictionary parameter.

How can I do that on the fly? Without creating a Dictionary variable.

EDIT TagBuilder is an example, there are other classes that accept a parameter IDictionary as well. The question is about the generic case.

A: 

If you're referring to the Attributes property, the setter is private, so you can't set it in an object initializer.

After you've initialized the TagBuilder, you should be able to add individual attributes with tr.Attributes.Add(key,value).

John Saunders
+1  A: 

The following blog post has a helper method that can create Dictionary objects from anonymous types.

http://weblogs.asp.net/rosherove/archive/2008/03/11/turn-anonymous-types-into-idictionary-of-values.aspx

void CreateADictionaryFromAnonymousType() 
   { 
       var dictionary = MakeDictionary(new {Name="Roy",Country="Israel"}); 
       Console.WriteLine(dictionary["Name"]); 
   }

private IDictionary MakeDictionary(object withProperties) 
   { 
       IDictionary dic = new Dictionary<string, object>(); 
       var properties = 
           System.ComponentModel.TypeDescriptor.GetProperties(withProperties); 
       foreach (PropertyDescriptor property in properties) 
       { 
           dic.Add(property.Name,property.GetValue(withProperties)); 
       } 
       return dic; 
   }
Robert Harvey
Robert, I don't see how that works in an object initializer.
John Saunders
It doesn't work for TagBuilder because, as you correctly pointed out, the setter is private.
Robert Harvey
+2  A: 

Another way to create Dictionaries from Anonymous types:

new Dictionary<int, StudentName>()
{
    { 111, new StudentName {FirstName="Sachin", LastName="Karnik", ID=211}},
    { 112, new StudentName {FirstName="Dina", LastName="Salimzianova", ID=317}},
    { 113, new StudentName {FirstName="Andy", LastName="Ruth", ID=198}}
};

http://msdn.microsoft.com/en-us/library/bb531208.aspx

Robert Harvey
A: 

Ok, so I was trying to do the same thing with the TagBuilder. Now my question is WHY is the Setter private on the Attributes property? Seems like it would be a nice shorthand way to use the TagBuilder to create a complete tag in one line (well, one semicolon at least...)

Oskar Austegard
In general, it's a bad idea to expose a collection property with a setter, as it allows the caller to replace your collection with his. You weren't trying to replace the collection in any case. You were trying to replace the contents of the collection. I agree there should be a syntax for that.
John Saunders
Right. Collection property setter = bad - agreed.I guess I was surprised that TagBuilder didn't act more like ActionLink (for instance), with its routeValues and htmlAttributes object parameters (which both end up as RouteValueDictionary instances).Wouldn't it make sense for TagBuilder to have the same syntax?
Oskar Austegard
Ok - TagBuilder has been "corrected": see http://gist.github.com/159291
Oskar Austegard