CheckBoxList برای فیلد Enum Flags مدل در ASP.Net MVC
نویسنده: پژمان پارسائی
تاریخ: ۱۳۹۲/۰۷/۳۰ ۲۳:۰
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
با توجه به اینکه دیگر قرار نیست به این لیست گزینه دیگری اضافه شود میتوانیم آنرا به صورت یک نوع داده شمارشی (Enum) تعریف کنیم. مثلا بدین صورت:
public enum Fabric
{
[Description("پنبه")]
Cotton,
[Description("ابریشم")]
Silk,
[Description("پشم")]
Wool,
[Description("ابریشم مصنوعی")]
Rayon,
[Description("پارچههای دیگر")]
Other
} public class MyViewModel
{
public Fabric Fabric { get; set; }
} [Flags]
public enum Fabric
{
[Description("پنبه")]
Cotton = 1,
[Description("ابریشم")]
Silk = 2,
[Description("پشم")]
Wool = 4,
[Description("ابریشم مصنوعی")]
Rayon = 8,
[Description("پارچههای دیگر")]
Other = 128
} Fabric cotWool = Fabric.Cotton | Fabric.Wool; int cotWoolValue = (int) cotWool;
public static IHtmlString CheckBoxesForEnumFlagsFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression)
{
ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
Type enumModelType = metadata.ModelType;
// Check to make sure this is an enum.
if (!enumModelType.IsEnum)
{
throw new ArgumentException("This helper can only be used with enums. Type used was: " + enumModelType.FullName.ToString() + ".");
}
// Create string for Element.
var sb = new StringBuilder();
foreach (Enum item in Enum.GetValues(enumModelType))
{
if (Convert.ToInt32(item) != 0)
{
var ti = htmlHelper.ViewData.TemplateInfo;
var id = ti.GetFullHtmlFieldId(item.ToString());
//Derive property name for checkbox name
var body = expression.Body as MemberExpression;
var propertyName = body.Member.Name;
var name = ti.GetFullHtmlFieldName(propertyName);
//Get currently select values from the ViewData model
TEnum selectedValues = expression.Compile().Invoke(htmlHelper.ViewData.Model);
var label = new TagBuilder("label");
label.Attributes["for"] = id;
label.Attributes["style"] = "display: inline-block;";
var field = item.GetType().GetField(item.ToString());
// Add checkbox.
var checkbox = new TagBuilder("input");
checkbox.Attributes["id"] = id;
checkbox.Attributes["name"] = name;
checkbox.Attributes["type"] = "checkbox";
checkbox.Attributes["value"] = item.ToString();
if ((selectedValues as Enum != null) && ((selectedValues as Enum).HasFlag(item)))
{
checkbox.Attributes["checked"] = "checked";
}
sb.AppendLine(checkbox.ToString());
// Check to see if DisplayName attribute has been set for item.
var displayName = field.GetCustomAttributes(typeof(DisplayNameAttribute), true)
.FirstOrDefault() as DisplayNameAttribute;
if (displayName != null)
{
// Display name specified. Use it.
label.SetInnerText(displayName.DisplayName);
}
else
{
// Check to see if Display attribute has been set for item.
var display = field.GetCustomAttributes(typeof(DisplayAttribute), true)
.FirstOrDefault() as DisplayAttribute;
if (display != null)
{
label.SetInnerText(display.Name);
}
else
{
label.SetInnerText(item.ToDescription());
}
}
sb.AppendLine(label.ToString());
// Add line break.
sb.AppendLine("<br />");
}
}
return new HtmlString(sb.ToString());
} public static string ToDescription(this Enum value)
{
var attributes = (DescriptionAttribute[])value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
return attributes.Length > 0 ? attributes[0].Description : value.ToString();
} @Html.CheckBoxesForEnumFlagsFor(x => x.Fabric)
public class FlagEnumerationModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (bindingContext == null) throw new ArgumentNullException("bindingContext");
if (bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName))
{
var values = GetValue<string[]>(bindingContext, bindingContext.ModelName);
if (values.Length > 1 && (bindingContext.ModelType.IsEnum && bindingContext.ModelType.IsDefined(typeof(FlagsAttribute), false)))
{
long byteValue = 0;
foreach (var value in values.Where(v => Enum.IsDefined(bindingContext.ModelType, v)))
{
byteValue |= (int)Enum.Parse(bindingContext.ModelType, value);
}
return Enum.Parse(bindingContext.ModelType, byteValue.ToString());
}
else
{
return base.BindModel(controllerContext, bindingContext);
}
}
return base.BindModel(controllerContext, bindingContext);
}
private static T GetValue<T>(ModelBindingContext bindingContext, string key)
{
if (bindingContext.ValueProvider.ContainsPrefix(key))
{
ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(key);
if (valueResult != null)
{
bindingContext.ModelState.SetModelValue(key, valueResult);
return (T)valueResult.ConvertTo(typeof(T));
}
}
return default(T);
}
} ModelBinders.Binders.Add(typeof(Fabric), new FlagEnumerationModelBinder());
public class ModelEnums
{
public static IEnumerable<Type> Types
{
get
{
var types = new List<Type> { typeof(Fabric) };
return types;
}
}
} foreach (var type in ModelEnums.Types)
{
ModelBinders.Binders.Add(type, new FlagEnumerationModelBinder())
} شکل (ب)