问题
In MVC 4, I have code similar to below,
@for (int i = 0; i < Model.dropDownControl.Count; i++)
{
@List<SelectListItem> fonts = (List<SelectListItem>)ViewBag.vFontlIst;
@Html.DropDownListFor(
model => model.dropDownControl[i].Font,
fonts,
new { style = "width: 100px; font-family:"+Model.dropDownControl[i].Font+"", id = "ddlFontDropDownList" })
}
Here i am trying to create dropdown similar to we have in MS Office for font selection, In above code dropdown font style is always same for complete list, Here selectlist contains list of all available font controller having code for this as,
List<SelectListItem> liFonts = new List<SelectListItem>();
foreach (FontFamily font in System.Drawing.FontFamily.Families)
{
liFonts.Add(new SelectListItem { Text = font.Name, Value = font.Name });
}
ViewBag.vFontlIst = liFonts;
I want here dropdown list to behave like Font dropdown of MS Office.
回答1:
You could do this in Javascript. A Jquery script could iterate over the option
elements in the select
and use the value of each as a font-family
$("#ddlFontDropDownList option").each(function(){
$(this).css("font-family":$(this).val());
});
EDIT:
I was wrong, you can't change the font for an option
tag. You need to replace the select
statement with a javascript widget which uses ol
/ li
instead.
Here's a working example of the HTML / Javascript to do that.
http://jsfiddle.net/6jnLD/
(based on the answer in this post)
You just need to output the ol
list in your view instead. That part should be easy.
EDIT2
What the hell, here's the View code too.
// Model
public List<FontFamily> Fonts { get; set; }
// Controller
List<FontFamily> liFonts = new List<FontFamily>();
foreach (FontFamily font in System.Drawing.FontFamily.Families)
{
liFonts.Add(font.Name);
}
and then the view
// View
<input id="font" type="hidden" name="ddlFontDropDownList" />
<h2 id="select_title">Choose Language</h2>
<ol class="select">
@foreach(System.Drawing.FontFamily font in fonts)
{
<li>@font.Name</li>
}
</ol>
回答2:
Thanks All,
After doing some workaround now able find the way to do this in mvc (Browser-Chrome),
I have write one custom html helper which extends @Html.DropDownListFor, And in that i did some customization in HTML to be rendered,
VIEW,
//Reference for customcontrol class
@using WEB_PDD_MVC.CustomHelpers
<div>
@{
List<SelectListItem> fonts = (List<SelectListItem>)ViewBag.vFontlIst;
foreach (SelectListItem item in fonts)
{
if (item.Text == Model.Font)
{
item.Selected = true;
}
else
{
item.Selected = false;
}
}
}
@Html.ExtendedDropDownListFor(model => model.Font, fonts,null, new { style = "width: 100px;", id = "ddlFontDropDownList" })
</div>
Controller,
List<SelectListItem> liFonts = new List<SelectListItem>();
liFonts.Add(new SelectListItem { Text = "nimbus-sans-condensed", Value = "nimbus-sans-condensed" });
//For now selecting only 10 fonts.
foreach (FontFamily font in System.Drawing.FontFamily.Families.Take(10))
{
liFonts.Add(new SelectListItem { Text = font.Name, Value = font.Name });
}
ViewBag.vFontlIst = liFonts;
For customdropdown class create a new folder,CustomHelpers and add new class file CustomDropDownList in it, add below methods in it,they will do the rest,
public static MvcHtmlString ExtendedDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, string optionLabel, object htmlAttributes)
{
return SelectInternal(htmlHelper, optionLabel, ExpressionHelper.GetExpressionText(expression), selectList, false /* allowMultiple */, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
private static MvcHtmlString SelectInternal(this HtmlHelper htmlHelper, string optionLabel, string name, IEnumerable<SelectListItem> selectList, bool allowMultiple, IDictionary<string, object> htmlAttributes)
{
string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
if (String.IsNullOrEmpty(fullName))
throw new ArgumentException("No name");
if (selectList == null)
throw new ArgumentException("No selectlist");
object defaultValue = null;
// If we haven't already used ViewData to get the entire list of items then we need to
// use the ViewData-supplied value before using the parameter-supplied value.
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;
}
// Convert each ListItem to an <option> tag
StringBuilder listItemBuilder = new StringBuilder();
// Make optionLabel the first item that gets rendered.
if (optionLabel != null)
listItemBuilder.Append(ListItemToOption(new SelectListItem() { Text = optionLabel, Value = String.Empty, Selected = false }));
foreach (SelectListItem item in selectList)
{
listItemBuilder.Append(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");
// If there are any errors for a named field, we add the css attribute.
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));
}
internal static string ListItemToOption(SelectListItem item)
{
TagBuilder builder = new TagBuilder("option")
{
InnerHtml = HttpUtility.HtmlEncode(item.Text)
};
if (item.Value != null)
{
builder.Attributes["value"] = item.Value;
//builder.Attributes["style"] = "background-color:Gray;";
}
if (item.Selected)
{
builder.Attributes["selected"] = "selected";
}
// builder.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(item.htmlAttributes));
TagBuilder OptGroup = new TagBuilder("optgroup ")
{
InnerHtml = builder.ToString(TagRenderMode.Normal)
};
OptGroup.Attributes["style"] = "display:none;font-family:" + item.Value + ";";
return OptGroup.ToString(TagRenderMode.Normal);
}
来源:https://stackoverflow.com/questions/22069490/in-mvc-it-possible-to-change-the-font-per-list-item-in-html-dropdownlistfor-cr