Html.DropdownListFor o valor selecionado não está sendo definido

97

Como posso definir o valor selecionado de um Html.DropDownListFor? Estive dando uma olhada online e vi que isso pode ser alcançado usando o quarto parâmetro, assim como o abaixo:

@Html.DropDownListFor(m => m, new SelectList(Model, "Code", "Name", 0),  "Please select a country")

Minha lista de seleção é exibida assim:

<select id="ShipFromCountries" name="ShipFromCountries">
     <option value="">Please select a country</option>
     <option value="GB">United Kingdom</option>
     <option value="US">United States</option>
     ...
</select>

Mas, por algum motivo, o Reino Unido continua selecionado, mas eu quero que "Selecione um país" seja selecionado.

Alguém sabe como posso conseguir isso?

EDITAR

Eu atualizei meu código, pois houve uma ligeira mudança na funcionalidade, mas ainda pareço estar encontrando esse problema. Isto é o que penso:

@Html.DropDownListFor(n => n.OrderTemplates, new SelectList(Model.OrderTemplates, "OrderTemplateId", "OrderTemplateName", 1), "Please select an order template")

1é o Id do optionque desejo selecionar, também tentei com o texto do optionmas também não funciona.

Alguma ideia?

Ibrar Hussain
fonte

Respostas:

181

Seu código tem alguns problemas conceituais:

Primeiro ,

@Html.DropDownListFor(n => n.OrderTemplates, new SelectList(Model.OrderTemplates, "OrderTemplateId", "OrderTemplateName", 1), "Please select an order template")

Ao usar DropDownListFor, o primeiro parâmetro é a propriedade onde o valor selecionado é armazenado depois de enviar o formulário. Então, no seu caso, você deve ter um SelectedOrderIdcomo parte de seu modelo ou algo parecido, a fim de usá-lo desta forma:

@Html.DropDownListFor(n => n.SelectedOrderId, new SelectList(Model.OrderTemplates, "OrderTemplateId", "OrderTemplateName", 1), "Please select an order template")

Segundo ,

Além de usar o ViewBag, isso não está errado, mas existem maneiras melhores (coloque essa informação no ViewModel), há um "pequeno bug" (ou um comportamento inesperado) quando sua propriedade ViewBag, onde você está segurando a SelectList, é o mesmo nome da propriedade onde você colocou o valor selecionado. Para evitar isso, basta usar outro nome ao nomear a propriedade que contém a lista de itens.

Algum código que eu usaria se fosse você para evitar esses problemas e escrever um código MVC melhor:

Viewmodel:

public class MyViewModel{
   public int SelectedOrderId {get; set;}
   public SelectList OrderTemplates {get; set;}

   // Other properties you need in your view
}

Controlador:

public ActionResult MyAction(){
   var model = new MyViewModel();
   model.OrderTemplates = new SelectList(db.OrderTemplates, "OrderTemplateId", "OrderTemplateName", 1);
   //Other initialization code

   return View(model);
}

Em sua visão:

@Html.DropDownListFor(n => n.SelectedOrderId, Model.OrderTemplates, "Please select an order template")
Romias
fonte
42
Salvei meu dia: "... há um pequeno bug quando sua propriedade ViewBag onde você está segurando a SelectList é o mesmo nome da propriedade onde você colocou o valor selecionado. Para evitar isso, basta usar outro nome ao nomear a propriedade que está segurando a lista de itens. " Obrigado!
Michael A. Volz, também conhecido como Flynn
4
Este "bichinho" é uma loucura absoluta! Perdi 2 horas da minha vida por causa disso. Como algo tão óbvio pode ainda existir e não ser corrigido?
cen
1
Flynn, seu comentário deveria ser uma resposta. Tentei implementações malucas para fazer minha lista suspensa funcionar e essa foi a solução simples
Dwayne Hinterlang
2
há um pequeno bug ? Não é um bug de forma alguma. A vinculação de modelo funciona vinculando-se ao valor de uma propriedade e quando você OrderTemplatesestá tentando vincular a uma ViewBagpropriedade que é typeof IEnumerabe<SelectListItem>. Mas um <select>elemento não pode ser vinculado a uma coleção de objetos complexos (apenas um tipo de valor)
Puta merda, eu teria perdido um dia inteiro se não fosse por essa resposta. Sério, esse LITTLE BUG é o motivo pelo qual devemos desistir do viewbag
Worthy7
22

Para mim não estava funcionando então funcionou desta forma:

Controlador:

int selectedId = 1;

ViewBag.ItemsSelect = new SelectList(db.Items, "ItemId", "ItemName",selectedId);

Visão:

@Html.DropDownListFor(m => m.ItemId,(SelectList)ViewBag.ItemsSelect)

JQuery:

$("document").ready(function () {
    $('#ItemId').val('@Model.ItemId');
});
VINICIUS SIN
fonte
2
Seu controlador tem o número errado de parênteses: ele tem um parêntese de abertura e dois parênteses de fechamento.
Amos Long
A lógica JQuery funciona para mim. Obrigado.
Shashank
7

Quando você passa um objeto como este:

new SelectList(Model, "Code", "Name", 0)

você está dizendo: a Fonte ( Model) e Chave ( "Code") o Texto ( "Name") e o valor selecionado 0. Provavelmente, você não tem um 0valor em sua fonte de Codepropriedade, portanto, o HTML Helper selecionará o primeiro elemento para passar o real selectedValue para este controle.

Felipe oriani
fonte
3

Certifique-se de ter aparado o valor selecionado antes de atribuir.

//Modelo

public class SelectType
{
    public string Text { get; set; }
    public string Value { get; set; }
}

//Controlador

var types = new List<SelectType>();
types.Add(new SelectType() { Value =  0, Text = "Select a Type" });
types.Add(new SelectType() { Value =  1, Text = "Family Trust" });
types.Add(new SelectType() { Value =  2, Text = "Unit Trust"});
ViewBag.PartialTypes = types;

//Visão

@Html.DropDownListFor(m => m.PartialType, new SelectList(ViewBag.PartialTypes, "Value", "Text"), new { id = "Type" })
Nalan Madheswaran
fonte
2

Se você sabe o que estará na visualização, também pode definir o valor padrão no Controlador, em vez de configurá-lo no arquivo view / cshtml. Não há necessidade de definir o valor padrão do lado HTML.

No arquivo do controlador.

commission.TypeofCommission = 1;
return View(commission);

No arquivo .cshtml.

@Html.DropDownListFor(row => row.TypeofCommission, new SelectList(Model.commissionTypeModelList, "type", "typeName"), "--Select--")
Smit Patel
fonte
1

Você deveria esquecer a aula

SelectList

Use isso em seu controlador:

var customerTypes = new[] 
{ 
    new SelectListItem(){Value = "all", Text= "All"},
    new SelectListItem(){Value = "business", Text= "Business"},
    new SelectListItem(){Value = "private", Text= "Private"},
};

Selecione o valor:

var selectedCustomerType = customerTypes.FirstOrDefault(d => d.Value == "private");
if (selectedCustomerType != null)
    selectedCustomerType.Selected = true;

Adicione a lista ao ViewData:

ViewBag.CustomerTypes = customerTypes;

Use isto em sua visão:

@Html.DropDownList("SectionType", (SelectListItem[])ViewBag.CustomerTypes)

-

Mais informações em: http://www.asp.net/mvc/overview/older-versions/working-with-the-dropdownlist-box-and-jquery/using-the-dropdownlist-helper-with-aspnet-mvc

g.breeze
fonte
0

Adicionar a seção do controlador

  ViewBag.Orders= new SelectList(db.Orders, "Id", "business", paramid);

Adicione a seção Html

   @Html.DropDownList("Orders", null)

Um método simples

ibrahim ozboluk
fonte
Um processamento de transação alternativa fácil
ibrahim ozboluk
0

Para mim solução geral :)

@{
     var selectedCity = Model.Cities.Where(k => k.Id == Model.Addres.CityId).FirstOrDefault();
     if (selectedCity != null)
     { 
         @Html.DropDownListFor(model => model.Addres.CityId, new SelectList(Model.Cities, "Id", "Name", selectedCity.Id), new { @class = "form-control" })
     }
     else
     { 
         @Html.DropDownListFor(model => model.Cities, new SelectList(Model.Cities, "Id", "Name", "1"), new { @class = "form-control" })
     }
}
Hamit YILDIRIM
fonte
0

Linq para lista suspensa com item vazio, item selecionado (funciona 100%)
(fortemente tipado, probabilidade de erro mínimo) Quaisquer alterações de modelo serão refletidas na ligação

Controlador

public ActionResult ManageSurveyGroup()
    {
        tbl_Survey sur = new tbl_Survey();
        sur.Survey_Est = "3";

        return View(sur);
    }

Visão

        @{


    //Step One : Getting all the list
    var CompEstdList = (from ComType in db.tbl_CompEstdt orderby ComType.Comp_EstdYr select ComType).ToList();

    //Step Two  : Adding a no Value item **
    CompEstdList.Insert(0, new eDurar.Models.tbl_CompEstdt { Comp_Estdid = 0, Comp_EstdYr = "--Select Company Type--" });

    //Step Three : Setting selected Value if value is present
    var selListEstd= CompEstdList.Select(s => new SelectListItem { Text = s.Comp_EstdYr, Value = s.Comp_Estdid.ToString() });

        }
        @Html.DropDownListFor(model => model.Survey_Est, selListEstd)
        @Html.ValidationMessageFor(model => model.Survey_Est)

Este método de ligação de dados também é possível

var selList = CompTypeList.Select(s => new SelectListItem { Text = s.CompTyp_Name, Value = s.CompTyp_Id.ToString(), Selected = s.CompTyp_Id == 3 ? true : false });

fonte
var selList = CompTypeList.Select (s => novo SelectListItem {Text = s.CompTyp_Name, Value = s.CompTyp_Id.ToString (), Selected = s.CompTyp_Id == 3? true: false});
0

Eu sei que isso não é realmente uma resposta para a pergunta, mas eu estava procurando uma maneira de inicializar o DropDownList a partir de uma lista no modo de exibição quando me deparei com este post.

Meu erro foi tentar criar uma SelectList a partir de um dicionário assim:

//wrong!
@Html.DropDownListFor(m => m.Locality, new SelectList(new Dictionary<string, string>() { { Model.Locality, Model.Locality_text } }, Model.Locality, ...

Então, fui vasculhar o documento oficial do msdn e descobri que DropDownListFornão necessariamente requer um SelectList, mas sim umIEnumerable<SelectListItem> :

//right
@Html.DropDownListFor(m => m.Locality, new List<SelectListItem>() { new SelectListItem() { Value = Model.Locality, Text = Model.Locality_text, Selected = true } }, Model.Locality, new { @class = "form-control select2ddl" })

No meu caso, provavelmente também posso omitir o Model.Locality item como selecionado, visto que é a) o único item eb) já o diz na SelectListItem.Selectedpropriedade.

Caso você esteja se perguntando, a fonte de dados é uma página AJAX, que é carregada dinamicamente usando o controle SelectWoo / Select2.

Damian Vogel
fonte
0
public byte UserType
public string SelectUserType

Você precisa obter um e definir um diferente. O valor selecionado não pode ser o mesmo item que você está prestes a definir.

@Html.DropDownListFor(p => p.SelectUserType, new SelectList(~~UserTypeNames, "Key", "Value",UserType))

Eu uso o dicionário Enum para minha lista, é por isso que existe o par "chave", "valor".

MEO
fonte
0

Eu tive um problema semelhante, estava usando o nome ViewBag e o elemento iguais. (Erro de digitação)

Arun Prasad ES
fonte
0

Este é um problema de CSS. Não sei por que @ Html.DropDownListFor no Bootstrap 4 funciona. Certamente este é um problema de design de classe. De qualquer forma, o trabalho é, se sua caixa de entrada suspensa tiver preenchimento CSS: #px, # px; elemento em seguida, desative-o. Espero que isso funcione.

naz hassan
fonte