【问题标题】:Set selected value in SelectList after instantiation实例化后在 SelectList 中设置选定值
【发布时间】:2008-11-19 13:16:23
【问题描述】:

我是否认为在创建后无法在 C# 类 SelectList 中设置选定值? 是不是有点傻?

【问题讨论】:

  • 我必须同意你的观点,因为这很愚蠢。 SelectList 似乎被故意“削弱”以迫使您创建更纯粹(和沉重)的视图模型。这种情况的一个特殊情况是,如果您想在表中重用选择列表,其中每一行都应基于视图模型中的另一个列表来选择其选定值。如果你想使用 SelectList,你实际上必须创建一个 SelectList 数组,每个数组都预先分配了它们的选定值,因为在你在特定行的剃刀视图代码中使用它之前,无法“动态”选择它。

标签: c# .net asp.net-mvc selectlist


【解决方案1】:

我认为您正在与框架作斗争。进入您的视图的数据应在最后一分钟 (LPM) 创建。

以这种方式思考,SelectList 是一种用于提供DropDownList HTML 帮助器的类型。它不是在您决定如何处理数据时存储数据的地方。

更好的解决方案是将您的数据检索到List<T>,然后在需要时初始化SelectList(s)。这种做法的直接好处是它允许您将List<T> 重复用于多个DropDownList,例如:

Country of birth
Country of residence

这些SelectLists 都使用List<Country> 类型的国家列表。

您可以在“最后一分钟”使用您的List<T>,如下例所示:

public class TaxCheatsFormViewModel
{
    private List<Country> countries { get; set; }

    public TaxCheat Cheat { get; private set; }
    public SelectList CountryOfBirth { get; private set; }
    public SelectList CountryOfResidence { get; private set; }
    public SelectList CountryOfDomicile { get; private set; }

    public TaxCheatsFormViewModel(TaxCheat baddie)
    {
        TaxCheat = baddie;
        countries = TaxCheatRepository.GetList<Country>();
        CountryOfBirth = new SelectList(countries, baddie.COB);
        CountryOfResidence = new SelectList(countries, baddie.COR);
        CountryOfDomicile = new SelectList(countries, baddie.COD);
    }
}

关键是您应该将数据保存在List&lt;T&gt; 中,直到您真正需要输出它;最后一分钟 (LPM)。

【讨论】:

  • 这确实是我走的路。在我看来,然后我从我的列表中创建一个 SelectList。在适用的情况下,我有一个辅助方法可以做到这一点。
【解决方案2】:

因为这在 Google 中的结果如此之高,所以我提供了我在这里找到的工作(尽管年龄):

如果您使用的是强类型视图(即模型具有分配的类型),则提供给 SelectList 的构造函数的 SelectedValue 将被用于页面模型的对象的值覆盖。

这在编辑页面上效果很好,但在您想要预选特定值时不适用于创建,因此一种解决方法是简单地在您作为模型传递给视图的默认构造对象上分配正确的值。 例如

var model = new SubjectViewModel()
{
   Subject = new Subject(),
   Types = data.SubjectTypes.ToList()
}
model.Subject.SubjectType = model.Types.FirstOrDefault(t => t.Id == typeId);
ViewData.Model = model;
return View();

所以我的创建视图中的代码如下所示:

Html.DropDownListFor(model => model.Subject.SubjectTypeId, new SelectList(model.Types, "Id", "Name"))

返回下拉列表,其值为我指定为列表中的 SelectedValue。

【讨论】:

    【解决方案3】:

    我知道这是一个老问题,但它可能会对那里的人有所帮助。我做了看起来与 Erik 所做的非常相似的事情。我刚刚从现有的 SelectList 创建了一个新的 SelectList...

    SelectList myList = GetMySelectList();
    SelectListItem selected = myList.FirstOrDefault(x => x.Text.ToUpper().Contains("UNITED STATES"));
    if (selected != null)
    {
         myList = new SelectList(myList, "value", "text", selected.Value);
    }
    

    【讨论】:

      【解决方案4】:

      “SelectedValue”属性是只读的。在构造函数中设置是唯一的方法。

      Tor,SelectList 是一个 ASP.NET MVC 构造,用于创建下拉列表。以你的方式做也应该有效,但如果做得好,SelectList 应该为你做(而不是在 JS 中)。

      【讨论】:

      • 为什么,看在上帝的份上,它是只读的?为什么不能在实例化后操作项目?那么为什么它不能作为只读数组公开呢?这种数据类型超出了我的范围!
      • 如果你不喜欢,写你自己的版本。没那么复杂,伙计。
      • @ will:是的,但我不认为我是唯一一个对 SelectList 类有这种感觉的人。那么我们应该自己写吗?
      【解决方案5】:

      我认为您可以在控制器中执行此操作。如果您要呈现一个带有名称/ID StateCode 的下拉列表,那么您可以在创建 SelectList 后使用此代码设置选定状态:

      ViewData["StateCode"] = "VT";

      似乎下拉列表 HTML 助手会查找与正在创建的下拉列表同名的 ViewData 项。

      我认为我不喜欢使用这种技术,但它似乎确实有效。

      我同意 SelectList 类目前有点弱。我希望能够创建一个 SelectList,然后稍后通过值或文本选择一个值。

      【讨论】:

      • 我注意到,当您在控制器和选择列表中使用常规集合时,它仅在视图的最后一刻才开始有意义。虽然我不是很喜欢那样,但它确实消除了很多摩擦......
      【解决方案6】:

      你的意思是客户端,在浏览器中?

      var select = document.getElementById('mySelect');
      select.options[newIndex].selected = true;
      

      【讨论】:

        【解决方案7】:

        SelectList 对象在创建后是只读的。如果你想选择一些你最好这样做的东西:

        <%= Html.DropDownList("clientId", ViewData["clients"] as List<SelectListItem>,)%>
        

        在后面的代码中:

            ViewData["clientId"] = "ASD"; //This should be the value of item you want to select
            ViewData["clients"] = clientItemList; //List<SelectListItem>
        

        【讨论】:

        • 我尽量远离背后的代码,因为这会在我的控制器、视图和背后的代码之间分配代码。我现在要做的是在视图中实例化 SelectListItem。不是我喜欢的方式,但这就是饼干碎的方式。
        【解决方案8】:

        用 jQuery 可以很容易地做到这一点;

        $(function() {
            $("#myselectlist option[@value='ItemToSelectValue'].attr('selected', 'true');
        });
        

        【讨论】:

        • 问题其实是在说C#类型的SelectList。我将更新 OP 以消除混乱。
        【解决方案9】:

        我自己需要一个带有预选下拉值的可编辑网格中的下拉列表。 Afaik,选择列表数据由控制器提供给视图,因此它是在视图使用它之前创建的。视图使用 SelectList 后,我​​将其交给使用标准 DropDownList 帮助器的自定义帮助器。所以,一个相当轻的解决方案imo。在撰写本文时,猜测它符合 ASP.Net MVC 精神;不开心的时候自己动手……

        public static string DropDownListEx(this HtmlHelper helper, string name, SelectList selectList, object selectedValue)
        {
            return helper.DropDownList(name, new SelectList(selectList.Items, selectList.DataValueField, selectList.DataTextField, selectedValue));
        }
        

        【讨论】:

          【解决方案10】:

          我同意@awrigley 和其他人的观点,在通常情况下,当您只有一个下拉列表时,最好使用选择列表构造函数加载选定的值。但是,有时,需要在视图上设置选定的值,例如当您有一个具有 n 个相同下拉列表的页面时。由于在控制器中创建这样的集合是不切实际的,甚至可能事先不知道您需要多少个下拉列表,因此更好的方法是在视图模型中创建一个实例作为没有选定值集的模板,然后动态创建其余的在视图上动态显示。

          当孩子需要下拉菜单时,我经常在编辑视图上遍历子项目列表时遇到这种情况。在这种情况下,你可以用一行代码做到这一点:

          @Html.DropDownListFor(x => myViewModelFieldName, new SelectList(Model.MyRawSelectListFromMyViewModel.Select(x=> new {x.Value, x.Text}), "Value", "Text", TheValueYouWantToSelect))
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-11-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多