DropDownListFor SelectedItem 的问题

发布于 2024-11-05 14:36:26 字数 1692 浏览 5 评论 0原文

这让我完全困惑不解。

这是我的观点:

@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;
    }
}

正如评论所暗示的那样,我无法让所选值发生。

这与我使用可为空的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() 并且没有区别。

这就像在创建 SelectListItem 时设置 Selected 属性没有任何效果,并且您在最后使用 SelectList ctor 参数设置它。

有人能解释一下吗?

This has totally puzzled me.

Here's my View:

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

And the model:

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;
    }
}

As the comments suggest, i can't get the selected value to happen.

Is it something to do with the fact i'm using a nullable decimal ? After that loop, options is correct in that it has exactly 1 item with select to true, so it seems i'm doing the right thing.

Now, if i use a different SelectList overload:

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

It works. Why? At first i thought it might be a LINQ-trick (e.g deferred execution), but i tried forcing a .ToList() and there is no difference.

It's like setting the Selected property as you create the SelectListItem has no effect, and you have you set it at the end using the SelectList ctor parameter.

Can anyone shed some light on this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

与君绝 2024-11-12 14:36:26

如果您查看 SelectList 类的实现,它实际上从未使用您传递 SelectListItem 的事实。它与 IEnumerable 一起使用。因此,不使用 SelectListItemSelected 属性。就我个人而言,我更喜欢通过设置将 ddl 绑定到的相应属性的值来设置下拉列表的 selected 值。

示例:

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 }
)

If you look at the implementation of the SelectList class it never actually uses the fact that you are passing a SelectListItem. It works with an IEnumerable. So the Selected property of a SelectListItem is not used. Personally I prefer setting the selected value of a dropdown by setting the value of the corresponding property that you are binding the ddl to.

Example:

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");
    }
}

and then in the controller action simply set the Score property to the necessary value and in the view use this Score property to bind to:

@Html.DropDownListFor(
    model => model.Score, 
    Model.RatingOptions, 
    "--", 
    new { @id = clientId }
)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文