在項目中有一個Html.DropDownListFor放在一個分部視圖中,然后調用這個分部視圖時需要動態控制這個DropDownList的顯示方式,比如寬度、是否禁用、是否列表等,這些值的設置都在Html.DropDownListFor的htmlAttributes參數中設置,如:
@Html.DropDownListFor(m => m.ClassID, ViewBag.List as SelectList, new { @style = "width:280px;", size = "20", disabled = "disabled" })
對於這個htmlAttributes,它可接受的數據類型可以是一個Object或IDictionary(string,Object),而我們在DropDownListFor擴展方法中所寫的new { @style = "width:280px;"}其實是一個匿名類。
題外話,關於匿名類
顧名思義 匿名類型就是沒有名字的類型。在C#3.0中允許我們在程序中聲明一個臨時的類型來存儲數據,例如:
class Program { static void Main(string[] args) { //聲明一個匿名對象,擁有 Name和Age 屬性 var obj = new { Name = "Joey", Age = 25 };//這里的new { Name = "Joey", Age = 25 } 就是一個匿名類型 ,obj則是這個類型的一個對象,稱為匿名對象 Console.WriteLine("匿名對象obj : Name=" + obj.Name + " , Age=" + obj.Age); } }
上述代碼中,我們聲明了一匿名對象obj ,然后輸出對象的屬性值。如果在VS 你將鼠標移到 obj前面的var 上面,vs 會提示:obj 是一個匿名類型 ‘a 。這個‘a 是編譯器自動作為標識的一個類型,匿名對象在編譯時,編譯器還是得給它一個類型,關於匿名類型的資料網上很多,為避免偏離主題,此處僅做示例。
通過非匿名類的方式動態控制htmlAttributes
知道了這個匿名類,我們可以象下面這種方式來調用:
var attList = new { @style = "width:280px;", size = "20" }; @Html.DropDownListFor(m => m.ClassID, ViewBag.List as SelectList, attList)
但是當我們試圖去更改屬性值的時候,VS會提示無法對屬性賦值,如圖:

這是因為這個匿名類的相關屬性只有get屬性,沒有set屬性。
接下來,我們通過建立一個非匿名類來實現htmlAttributes的動態調用。
建立一個cs文件,然后在這個cs文件中新建一個htmlAttributes屬性類,代碼如下:
public class AttClass { public string style { get; set; } public string size { get; set; } }
然后在VIEW中實例化這個類並為其屬性賦值:
AttClass att = new AttClass(); att.size = "20"; att.style = "width:800px";
完成后就可以在DropDownListFor中使用這個實例化的對象了
@Html.DropDownListFor(m => m.ClassID, ViewBag.List as SelectList, att)
通過IDictionary字典實現動態控制htmlAttributes屬性
htmlAttributes可接受的數據類型可以是IDictionary(string,Object),那我們可以直接在代碼中使用字典的方式添加屬性,然后為DropDownListFor賦值:
IDictionary<string, object> att = new Dictionary<string, object>(); att.Add("size","30"); att.Add("style", "width:280px;"); @Html.DropDownListFor(m => m.ClassID, ViewBag.List as SelectList, att)
總結
應用非匿名類及字典的方式都可以實現對htmlAttributes的動態控制,實際使用中,IDictionary的代碼量較少,應用也比較靈活。
補充:關於動態控制routeValues的方法
比如我們調用一個Url.Action方法,其中的routeValues不能直接使用上面的IDictionary來實現,但可以使用RouteValueDictionary來實現。
@{ RouteValueDictionary att = new RouteValueDictionary(); att.Add("tbPre", "Module"); att.Add("FirstText", "作為一級分類"); if (!string.IsNullOrEmpty(Html.ViewContext.RouteData.Values["id"].ToString())) { att.Add("SelectedValue", Html.ViewContext.RouteData.Values["id"]); } } @Html.Action("index", "ClassList", att)
另外,RouteValueDictionary的構造函數也提供了在初始化RouteValueDictionary對象的時候將IDictionary復制元素到RouteValueDictionary中的方法。
