如何在C#中删除或禁用Html.EnumDropDownListFor中的项目

时间:2018-01-18 00:23:32

标签: c# asp.net-mvc razor enumdropdownlistfor

我的ASP.Net MVC网站上有一个EnumDropDownListFor,代表来自枚举的时间列表(例如,上午5:00,上午5:15,上午5:30到下午9:00,以15分钟为增量) / p>

amount += transactions[j].amount

我在视图中显示所有这样的时间

public enum YogaTime
{
    [Display(Name = "5:00 AM")]
    Five,
    [Display(Name = "5:15 AM")]
    FiveFifteen,
    [Display(Name = "5:30 AM")]
    FiveThirty,
    [Display(Name = "5:45 AM")]
    FiveFortyFive,
    [Display(Name = "6:00 AM")]
    Six,
    ...
    ...
    ...
    [Display(Name = "9:00 PM")]
    Nine,
}

是否有一种简单的方法可以删除或禁用当前时间之前的所有时间?恩。如果它是2:00 PM在下午2:00之前删除或禁用所有时间

仅供参考 - 我使用bootstrap selectpicker来设置下拉列表的样式。

3 个答案:

答案 0 :(得分:0)

基本思想是为YogaTime分配一个与时间相关的整数值。我使用从一天开始时开始的总分钟数作为每个YogaTime的值(Hour * 60 + Minute)。

public enum YogaTime
{
    [Display(Name = "5:00 AM")]
    Five = 300,                // 5 * 60 + 0
    [Display(Name = "5:15 AM")]
    FiveFifteen = 315,         // 5 * 60 + 15
    [Display(Name = "5:30 AM")]
    FiveThirty = 330,          // 5 * 60 + 30
    [Display(Name = "5:45 AM")]
    FiveFortyFive = 345,       // 5 * 60 + 45
    [Display(Name = "6:00 AM")]
    Six = 360,                 // 6 * 60 + 0
    [Display(Name = "7:00 PM")]
    Seven = 1140,              // 19 * 60 + 0
    [Display(Name = "9:00 PM")]
    Nine = 1260,               // 21 * 60 + 0
}

然后,您可以使用DropDownListFor过滤掉那些过去的时间段,这也可以在Controller方法中完成,并通过ViewBag传递结果。

@using System.ComponentModel.DataAnnotations
@using WebApplication1.Models
@model YogaViewModel
@{
    var now = DateTime.Now;
    var yogaTimes = Enum.GetValues(typeof(YogaTime)).Cast<int>().Where(t => t > now.Hour * 60 + now.Minute).Cast<YogaTime>();
    var selectList = new List<SelectListItem>();
    foreach (var yogaTime in yogaTimes)
    {
        var memberInfo = typeof(YogaTime).GetMember(yogaTime.ToString());
        if (memberInfo.Length == 0) { continue; }
        var attributes = memberInfo[0].GetCustomAttributes(typeof(DisplayAttribute), false);
        if (attributes.Length == 0) { continue; }
        var displayAttribute = attributes[0] as DisplayAttribute;
        if (displayAttribute == null) { continue; }
        selectList.Add(new SelectListItem
        {
            Value = ((int)yogaTime).ToString(),
            Text = displayAttribute.Name
        });
    }
}

<div class="col-sm-6" style="padding-left: 0px; padding-right: 0px;">
    @Html.DropDownListFor(m => m.StartTime, selectList, new { @class = "form-control selectpicker", @name = "StartTime" })
</div>

答案 1 :(得分:0)

假设你有这样的自定义值的枚举(我使用类似于军事时间的24小时格式):

public enum YogaTime
{
    [Display(Name = "12:00 AM")]
    Zero = 0,
    [Display(Name = "12:15 AM")]
    ZeroFifteen = 15,
    [Display(Name = "12:30 AM")]
    ZeroThirty = 30,
    [Display(Name = "12:45 AM")]
    ZeroFortyFive = 45,
    [Display(Name = "1:00 AM")]
    One = 100,

    // other values

    [Display(Name = "9:00 PM")]
    TwentyOne = 2100,
}

基于类似问题here的解决方案,您需要执行以下步骤:

1)创建GetDisplayName方法以显示枚举值。

// taken from /a/32193206
public static string GetDisplayName(this Enum enum)
{
    Type enumType = enumeration.GetType();
    string enumName = Enum.GetName(enumType, enumeration);
    string displayName = enumName;
    try
    {
        MemberInfo member = enumType.GetMember(enumName)[0];

        object[] attributes = member.GetCustomAttributes(typeof(DisplayAttribute), false);
        DisplayAttribute attribute = (DisplayAttribute)attributes[0];
        displayName = attribute.Name;

        if (attribute.ResourceType != null)
        {
            displayName = attribute.GetName();
        }
    }
    catch (Exception e) { }
    return displayName;
}

2)创建声明为List<SelectListItem>的viewmodel属性以保存下拉列表值,例如EnumSelectList

3)在控制器动作方法中放入所需条件,如本例所示:

var model = new ViewModel();

// cast to proper enum values with current hour & minute
YogaTime hour = (YogaTime)((DateTime.Now.Hour * 100) + DateTime.Now.Minute);

model.EnumSelectList = Enum.GetValues(typeof(YogaTime))
               .Cast<YogaTime>().Where(x => x >= hour)
               .Select(x => new SelectListItem() 
               {
                    Value = ((int)x).ToString(),
                    Text = ((Enum)(object)x).GetDisplayName()
               }).ToList();

return View(model);

4)在视图中,EnumDropDownListFor应更改为DropDownListFor,因为枚举值在编译时是硬编码的。

@Html.DropDownListFor(model => model.StartTime, Model.EnumSelectList, new { @class = "form-control selectpicker" })

检查实例:.NET Fiddle

答案 2 :(得分:0)

1º:将您的方法更改为DropDownListFor,签名具有SelectList的额外参数,它是可以在控件上显示的值。

2º:在枚举上使用此扩展方法构建选择列表:

 public static SelectList ToSelectList<TEnum>(this TEnum enumObj,
                                                      Func<TEnum, string> getText = null,
                                                      Func<TEnum, object> getValue = null,
                                                      Func<TEnum, bool> ignore = null)
    {
        var query = Enum.GetValues(typeof(TEnum)).Cast<TEnum>();

        if (ignore != null)
            query = query.Where(e => !ignore(e));

        var values = query.Select(e =>
        {   
            object value = getValue != null ? getValue(e) : e;

            string name = null;

            if (getText != null)
                name = getText(e);

            name = name ?? EnumExtension.GetDisplayName((Enum)(object) e) ?? e.ToString();

            return new { @Name = name, @Value = value };
        });

        return new SelectList(values, "Value", "Name", enumObj);
    }

3º:最后一个可选参数允许您编写一个过滤器来忽略这些值。

4º:您必须从EnumValue获取显示属性,使用如下静态方法:How to get the Display Name Attribute of an Enum member via MVC razor code?

5º:对于Last,您必须将显示字符串解析为DateTime并将其与DateTime.UtcNow进行比较。

所以代码(密集形式,可以重构并更改使用Parse到TryParse)应该是这样的:

@Html.DropDownListFor(m => m.StartTime,
                      YogaTime.ToSelectList(t =>         
                          DateTime.Parse(t.GetDisplayName()) <= 
                          DateTime.UtcNow)),
                      new { @class = "form-control selectpicker" })

额外:这是你想要的方式,现在我想建议不要在.cshtml上构建这个

你可以做同样的事情,但是在Controller上构建SelectList并使用ViewBag,就像那样:

 @Html.DropDownListFor(m => m.StartTime,
                      (SelectList)ViewBag.Times,
                      new { @class = "form-control selectpicker" })

ViewBag是用于视图上的动态操作的ExpandoObject,可以使用我之前提到或解释过的相同方法构建。

希望它有帮助!