Проблема с DropDownList для выбранного элемента - PullRequest
3 голосов
/ 05 мая 2011

Это меня совершенно озадачило.

Вот мой взгляд:

@Html.DropDownListFor(model => model.ScoreDescription, 
                               Model.RatingOptions, 
                               "--", 
                               new { @id = clientId })

И модель:

public decimal? Score { get; set; }
public SelectList RatingOptions
{ 
    get
    {
        var options = new List<SelectListItem>();

        for (var i = 1; i <= 5; i++)
        {
            options.Add(new SelectListItem
            {
                Selected = Score.HasValue && Score.Value == Convert.ToDecimal(i),
                Text = ((decimal)i).ToRatingDescription(ScoreFactorType),
                Value = i.ToString()
            });
        }

        var selectList = new SelectList(options, "Value", "Text");
            // At this point, "options" has an item with "Selected" to true.
            // Also, the underlying "MultiSelectList" also has it.
            // Yet selectList.SelectedValue is null. WTF?
        return selectList;
    }
}

Как показывают комментарии, я не могуполучить выбранное значение.

Это как-то связано с тем, что я использую nullable decimal?После этого цикла options является верным в том смысле, что в нем ровно 1 элемент с select в true, поэтому, похоже, я поступаю правильно.

Теперь, если я использую другой SelectList перегрузка:

var selectedValue = Score.HasValue ? Score.Value.ToString("0") : string.Empty;
var selectList = new SelectList(options, "Value", "Text", selectedValue);

Работает.Зачем?Сначала я подумал, что это может быть трюк LINQ (например, отложенное выполнение), но я попытался форсировать .ToList(), и нет никакой разницы.

Это похоже на установку свойства Selected при создании SelectListItem не имеет никакого эффекта, и вы установили его в конце, используя параметр SelectList ctor.

Может кто-нибудь пролить свет на это?

1 Ответ

4 голосов
/ 05 мая 2011

Если вы посмотрите на реализацию класса SelectList, он фактически никогда не использует тот факт, что вы передаете SelectListItem.Он работает с IEnumerable.Таким образом, свойство Selected для SelectListItem не используется.Лично я предпочитаю устанавливать значение selected раскрывающегося списка, устанавливая значение соответствующего свойства, к которому привязывается ddl.

Пример:

public int? Score { get; set; }
public SelectList RatingOptions
{ 
    get
    {
        var options = Enumerable.Range(1, 5).Select(i => new SelectListItem
        {
            Text = ((decimal)i).ToRatingDescription(ScoreFactorType),
            Value = ((decimal)i).ToString()
        });
        return new SelectList(options, "Value", "Text");
    }
}

изатем в действии контроллера просто установите для свойства Score необходимое значение и в представлении используйте это свойство Score для привязки к:

@Html.DropDownListFor(
    model => model.Score, 
    Model.RatingOptions, 
    "--", 
    new { @id = clientId }
)
...