ASP.NET MVC DropDownList擴展,實現[email protected](p=>p.Type,p.Type,TypeItem)

頁面數據輸入的是一個List<TModel>的時。

用foreach(var item in Models)的時候

其中有Item 類裏有Type屬性,他們是枚舉或是關聯其它表的數據

此時要用DropDownList顯示出來出來

如 Type: 1-小說;2-散文;3-詩;4-詞;

var typeItem = new List<SelectListItem>(){
    new SelectListItem(){ Value = "1",Text = "小說" },
    new SelectListItem(){ Value = "2",Text = "散文" },
    new SelectListItem(){ Value = "3",Text = "詩" },
    new SelectListItem(){ Value = "4",Text = "詞" },
};

cshtml界面

<table>
    <tr>
	<th>
	    序號
	</th>
	<th>
    	    類型
	</th>
    </tr>
foreach(var item in Mode)
{
    <tr>
        <td>
	    item.id
	</td>
        <td>
            @Html.DropDownListFor(item=>item.Type,typeItem);
        </td>
	<td>
	....
	</td>
    </td>  
}
</table>
老是顯示第一個,明明將Type傳入進去了,可還是不行。

如圖所示

後來下載了MVC代碼看了一下,原來在獲取值的時候沒有區分當前Type是

Lambda來至 List<TMode> 還是TModel

如果是TModel的話,傳入Type是可以正確顯示的

而在用List<TMode>的時候,就不行了

頁面會將整個List<TModel>傳入到後臺去

這樣他不知道當前如何去取當前是哪個TModel裏Type裏的值

於是我就增加了一個擴展,將當前的值,同時傳入到後臺去

這樣就可以很好的顯示出來了

@Html.DropDownListFor(item=>item.Type,typeItem);

改爲

@Html.DropDownListFor(item=>item.Type,item.Type,typeItem);


下面把我寫的擴展代碼貼出來

個人水平有限

如果有什麼不對地方,還望指整

using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Web;
using System.Web.Mvc;

namespace Photography.CoreUI
{
    /// <summary>
    /// 下拉框擴展
    /// mailto:[email protected]
    /// 我的BLOG http://blog.csdn.net/xiaotuni
    /// </summary>
    public static class XiaotuniDropDownListExtensions
    {
        static string MvcResources_HtmlHelper_MissingSelectData = "Missing Select Data";
        static string MvcResources_HtmlHelper_WrongSelectDataType = "Wrong Select Data Type";
        static string MvcResources_Common_NullOrEmpty = "Null Or Empty";

        /// <summary>
        /// 創建一個DropDownList控件
        /// </summary>
        /// <typeparam name="TModel">當前數據</typeparam>
        /// <typeparam name="TProperty">屬性</typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression">lambda 表達式</param>
        /// <param name="defaultValue">默認值</param>
        /// <param name="selectList">DropDownList裏的數據</param>
        /// <returns></returns>
        public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, 
            Expression<Func<TModel, TProperty>> expression, object defaultValue, IEnumerable<SelectListItem> selectList)
        {
            return DropDownListFor(htmlHelper, expression, defaultValue, selectList, null, null);
        }
        /// <summary>
        /// 創建一個DropDownList控件
        /// </summary>
        /// <typeparam name="TModel">當前數據</typeparam>
        /// <typeparam name="TProperty">屬性</typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression">lambda 表達式</param>
        /// <param name="defaultValue">默認值</param>
        /// <param name="selectList">DropDownList裏的數據</param>
        /// <param name="optionLabel">標籤名稱</param>
        /// <param name="htmlAttributes">DorpDownList屬性</param>
        /// <returns></returns>
        public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object defaultValue, IEnumerable<SelectListItem> selectList, string optionLabel, IDictionary<string, object> htmlAttributes)
        {
            if (expression == null)
            {
                throw new ArgumentNullException("expression");
            }
            string name = ExpressionHelper.GetExpressionText(expression);
            return SelectInternal(htmlHelper, optionLabel, name, selectList, defaultValue, false, htmlAttributes);
        }

        /// <summary>
        /// 獲取選中項數據
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        static IEnumerable<SelectListItem> GetSelectData(this HtmlHelper htmlHelper, string name)
        {
            object o = null;
            if (htmlHelper.ViewData != null)
            {
                o = htmlHelper.ViewData.Eval(name);
            }
            if (o == null)
            {
                throw new InvalidOperationException(
                    String.Format(
                        CultureInfo.CurrentCulture,
                        MvcResources_HtmlHelper_MissingSelectData,
                        name,
                        "IEnumerable<SelectListItem>"));
            }
            IEnumerable<SelectListItem> selectList = o as IEnumerable<SelectListItem>;
            if (selectList == null)
            {
                throw new InvalidOperationException(
                    String.Format(
                        CultureInfo.CurrentCulture,
                        MvcResources_HtmlHelper_WrongSelectDataType,
                        name,
                        o.GetType().FullName,
                        "IEnumerable<SelectListItem>"));
            }
            return selectList;
        }

        static object GetModelStateValue(HtmlHelper htmlHelper, string key, Type destinationType)
        {
            ModelState modelState;
            if (htmlHelper.ViewContext.ViewData.ModelState.TryGetValue(key, out modelState))
            {
                if (modelState.Value != null)
                {
                    return modelState.Value.ConvertTo(destinationType, null /* culture */);
                }
            }
            return null;
        }

        static string ListItemToOption(SelectListItem item)
        {
            TagBuilder builder = new TagBuilder("option")
            {
                InnerHtml = HttpUtility.HtmlEncode(item.Text)
            };
            if (item.Value != null)
            {
                builder.Attributes["value"] = item.Value;
            }
            if (item.Selected)
            {
                builder.Attributes["selected"] = "selected";
            }
            return builder.ToString(TagRenderMode.Normal);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="optionLabel"></param>
        /// <param name="name"></param>
        /// <param name="selectList"></param>
        /// <param name="selectedValue"></param>
        /// <param name="allowMultiple"></param>
        /// <param name="htmlAttributes"></param>
        /// <returns></returns>
        static MvcHtmlString SelectInternal(this HtmlHelper htmlHelper, string optionLabel, string name, IEnumerable<SelectListItem> selectList, object selectedValue, bool allowMultiple, IDictionary<string, object> htmlAttributes)
        {
            string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
            if (String.IsNullOrEmpty(fullName))
            {
                throw new ArgumentException(MvcResources_Common_NullOrEmpty, "name");
            }

            bool usedViewData = false;

            if (selectList == null)
            {
                selectList = htmlHelper.GetSelectData(fullName);
                usedViewData = true;
            }


            object defaultValue = selectedValue != null ? selectedValue : (allowMultiple) ? GetModelStateValue(htmlHelper, fullName, typeof(string[])) : GetModelStateValue(htmlHelper, fullName, typeof(string));

            if (!usedViewData)
            {
                if (defaultValue == null)
                {
                    defaultValue = htmlHelper.ViewData.Eval(fullName);
                }
            }

            if (defaultValue != null)
            {
                IEnumerable defaultValues = (allowMultiple) ? defaultValue as IEnumerable : new[] { defaultValue };
                IEnumerable<string> values = from object value in defaultValues select Convert.ToString(value, CultureInfo.CurrentCulture);
                HashSet<string> selectedValues = new HashSet<string>(values, StringComparer.OrdinalIgnoreCase);
                List<SelectListItem> newSelectList = new List<SelectListItem>();

                foreach (SelectListItem item in selectList)
                {
                    item.Selected = (item.Value != null) ? selectedValues.Contains(item.Value) : selectedValues.Contains(item.Text);
                    newSelectList.Add(item);
                }
                selectList = newSelectList;
            }

            StringBuilder listItemBuilder = new StringBuilder();

            if (optionLabel != null)
            {
                listItemBuilder.AppendLine(ListItemToOption(new SelectListItem() { Text = optionLabel, Value = String.Empty, Selected = false }));
            }

            foreach (SelectListItem item in selectList)
            {
                listItemBuilder.AppendLine(ListItemToOption(item));
            }

            TagBuilder tagBuilder = new TagBuilder("select")
            {
                InnerHtml = listItemBuilder.ToString()
            };
            tagBuilder.MergeAttributes(htmlAttributes);
            tagBuilder.MergeAttribute("name", fullName, true /* replaceExisting */);
            tagBuilder.GenerateId(fullName);
            if (allowMultiple)
            {
                tagBuilder.MergeAttribute("multiple", "multiple");
            }

            ModelState modelState;
            if (htmlHelper.ViewData.ModelState.TryGetValue(fullName, out modelState))
            {
                if (modelState.Errors.Count > 0)
                {
                    tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);
                }
            }

            tagBuilder.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(name));

            return MvcHtmlString.Create(tagBuilder.ToString(TagRenderMode.Normal));
        }
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章