One option is to create a custom version of Html.DropDownList that takes an additional parameter and does what you want ... but then you will need to create a new one for each type of helper - TextBoxFor, TextAreaFor, CheckBoxFor, etc ... and you still need to figure out how to make it work.
Instead, I decided to create an Html Helper to replace the usual anonymous HtmlAttributes object, as it will be compatible with all helpers that use HtmlAttributes without any special work. This solution also allows you to pass additional attributes like Class, Name or whatever. It does not block you only by disconnecting.
I created the following Helper - it accepts a logical and anonymous object. If the value is disabled, it adds the disabled attribute to the anonymous object (which is actually a Dictionary) with the value "disabled", otherwise it does not add the property at all.
public static RouteValueDictionary ConditionalDisable( bool disabled, object htmlAttributes = null) { var dictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes); if (disabled) dictionary.Add("disabled", "disabled"); return dictionary; }
An example of this in action:
@Html.TextBoxFor(m => m.SomeProperty, HtmlHelpers.ConditionalDisable(true, new { @class = "someClass"))
The huge advantage of this approach for me was that it works with almost all MVC HtmlHelpers, since they all have Overloads that accept RouteValueDictionary instead of an anonymous object.
Caution :
HtmlHelper.AnonymousObjectToHtmlAttributes () uses some ninja fancy code work to get things done. I'm not quite sure how effective it is ... but that was enough for what I use it for. Your mileage may vary.
I do not like this name, but I could not think of anything better. Renaming is easy.
I also do not like the syntax of use, but again I could not think of anything better. It should not be difficult to change. The extension method on object is one idea ... you will get new { @class = "someClass" }.ConditionalDisable(true) , but then if you only need the disable attribute and you have nothing more to add to what you something bigger, for example new {}.ConditionalDisable(true); and you also get an extension method that displays for all objects ... which is probably not desirable.