c# - SelectList с нулевым выбором




.net asp.net-mvc (2)

У меня есть несколько выпадающих списков, таких как этот:

@Html.DropDownListFor(model => model.Process, Model.ProcessList)

Все они принимают SelectList на основе данных из таблицы базы данных, например:

ProcessList = new SelectList(_db.Processes, "ID", "Name");

где _db.Processes возвращает ObjectSet<Process> .

Проблема у меня заключается в том, что иногда свойство, которое устанавливается раскрывающимся списком, может быть без выбора, то есть с null . Как я могу добавить null выбор в SelectList >


Answers

@Html.DropDownListFor(model => model.Process, Model.ProcessList,"--Select Process--")

Приведенная выше строка добавит --select process-- вверху списка выбора, и если выбрано это значение, пустая строка будет опубликована, а привязанному свойству будет --select process-- значение null (в этом случае Process)


Для этого я создал интерфейс и <options> . Поэтому мне не приходилось преобразовывать элементы IEnumerable<T> в IEnumerable<SelectListItem> каждый раз, когда я должен заполнить элемент управления <select> .

И я думаю, что это прекрасно работает ...

Использование - это что-то вроде:

<select asp-for="EmployeeId">
    <option value="">Please select...</option>
    <options asp-items="@Model.EmployeesList" />
</select>

Чтобы заставить его работать с помощником тега, вы должны реализовать этот интерфейс в своем классе:

public class Employee : IIntegerListItem
{
   public int Id { get; set; }
   public string FullName { get; set; }

   public int Value { return Id; }
   public string Text{ return FullName ; }
}

Это необходимые коды:

Интерфейс:

public interface IIntegerListItem
{
    int Value { get; }
    string Text { get; }
}

Хелпер <options> :

[HtmlTargetElement("options", Attributes = "asp-items")]
public class OptionsTagHelper : TagHelper
{
    public OptionsTagHelper(IHtmlGenerator generator)
    {
        Generator = generator;
    }

    [HtmlAttributeNotBound]
    public IHtmlGenerator Generator { get; set; }

    [HtmlAttributeName("asp-items")]
    public object Items { get; set; }

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        output.SuppressOutput();
        // Is this <options /> element a child of a <select/> element the SelectTagHelper targeted?
        object formDataEntry;
        context.Items.TryGetValue(typeof(SelectTagHelper), out formDataEntry);

        var selectedValues = formDataEntry as ICollection<string>;
        var encodedValues = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
        if (selectedValues != null && selectedValues.Count != 0)
        {
            foreach (var selectedValue in selectedValues)
            {
                encodedValues.Add(Generator.Encode(selectedValue));
            }
        }

        IEnumerable<SelectListItem> items = null;
        if (Items != null)
        {
            if (Items is IEnumerable)
            {
                var enumerable = Items as IEnumerable;
                if (Items is IEnumerable<SelectListItem>)
                    items = Items as IEnumerable<SelectListItem>;
                else if (Items is IEnumerable<IIntegerListItem>)
                    items = ((IEnumerable<IIntegerListItem>)Items).Select(x => new SelectListItem() { Selected = false, Value = ((IIntegerListItem)x).Value.ToString(), Text = ((IIntegerListItem)x).Text });
                else
                    throw new InvalidOperationException(string.Format("The {2} was unable to provide metadata about '{1}' expression value '{3}' for <options>.",
                        "<options>",
                        "ForAttributeName",
                        nameof(IModelMetadataProvider),
                        "For.Name"));
            }
            else
            {
                throw new InvalidOperationException("Invalid items for <options>");
            }

            foreach (var item in items)
            {
                bool selected = (selectedValues != null && selectedValues.Contains(item.Value)) || encodedValues.Contains(item.Value);
                var selectedAttr = selected ? "selected='selected'" : "";

                if (item.Value != null)
                    output.Content.AppendHtml($"<option value='{item.Value}' {selectedAttr}>{item.Text}</option>");
                else
                    output.Content.AppendHtml($"<option>{item.Text}</option>");
            }
        }
    }
}

Может быть, есть опечатка, но цель ясна, я думаю. Мне пришлось немного отредактировать.





c# .net asp.net-mvc