Estou tentando usar o Html.DropDownList
método de extensão, mas não consigo descobrir como usá-lo com uma enumeração.
Digamos que eu tenho uma enumeração como esta:
public enum ItemTypes
{
Movie = 1,
Game = 2,
Book = 3
}
Como faço para criar uma lista suspensa com esses valores usando o Html.DropDownList
método de extensão?
Ou é a minha melhor aposta para simplesmente criar um loop for e criar os elementos HTML manualmente?
c#
asp.net
asp.net-mvc
Kevin Pang
fonte
fonte
ASP.NET MVC
Eu sei que estou atrasado para a festa, mas achei que você poderia achar essa variante útil, pois essa também permite que você use sequências descritivas em vez de constantes de enumeração no menu suspenso. Para fazer isso, decore cada entrada de enumeração com um atributo [System.ComponentModel.Description].
Por exemplo:
Aqui está o meu código:
Você pode fazer isso na sua visão:
Espero que isso ajude você!
** EDIT 2014-JAN-23: A Microsoft acaba de lançar o MVC 5.1, que agora possui o recurso EnumDropDownListFor. Infelizmente, ele não parece respeitar o atributo [Descrição], portanto o código acima ainda permanece. Consulte a seção Enum nas notas de versão da Microsoft para MVC 5.1.
Atualização: No entanto, ele suporta o atributo Display
[Display(Name = "Sample")]
, para que você possa usá-lo.[Atualização - acabei de notar isso, e o código se parece com uma versão estendida do código aqui: https://blogs.msdn.microsoft.com/stuartleeks/2010/05/21/asp-net-mvc-creating-a- dropdownlist-helper-for-enums / , com algumas adições. Nesse caso, a atribuição pareceria justa ;-)]
fonte
System.Web.Mvc.Html
, ele diz queDropDownListFor
não pode ser encontrado, mas também não pode resolvê-lo. Você tem que fazer manualmenteusing System.Web.Mvc.Html;
. Só para você saber.No ASP.NET MVC 5.1 , eles adicionaram o
EnumDropDownListFor()
auxiliar, portanto, não há necessidade de extensões personalizadas:Modelo :
Ver :
Usando o Assistente de Tags (ASP.NET MVC 6) :
fonte
Encontrei o mesmo problema, encontrei essa pergunta e pensei que a solução fornecida por Ash não era o que eu estava procurando; Ter que criar o HTML sozinho significa menos flexibilidade em comparação com a
Html.DropDownList()
função interna.Acontece que C # 3 etc. torna isso muito fácil. Eu tenho um
enum
chamadoTaskStatus
:Isso cria uma boa
SelectList
aparência que pode ser usada como você está acostumado na exibição:O tipo anônimo e o LINQ tornam esse IMHO muito mais elegante. Sem querer ofender, Ash. :)
fonte
select new { ID = (int)s, Name = s.ToString() };
Aqui está uma solução encapsulada melhor:
https://www.spicelogic.com/Blog/enum-dropdownlistfor-asp-net-mvc-5
Diga aqui está o seu modelo:
Uso da amostra:
UI gerada:
E gerado HTML
A captura instantânea do código-fonte da extensão auxiliar:
Você pode baixar o projeto de amostra no link que forneci.
EDIT: Aqui está o código:
fonte
Html.DropDownListFor requer apenas um IEnumerable, portanto, uma alternativa à solução do Prise é a seguinte. Isso permitirá que você escreva simplesmente:
[Onde SelectedItemType é um campo no seu modelo do tipo ItemTypes e seu modelo não é nulo]
Além disso, você realmente não precisa generalizar o método de extensão, pois pode usar enumValue.GetType () em vez de typeof (T).
EDIT: Solução integrada do Simon aqui também, e incluiu o método de extensão ToDescription.
fonte
Portanto, sem as funções de extensão, se você estiver procurando por algo simples e fácil .. Foi o que eu fiz
onde XXXXX.Sites.YYYY.Models.State é uma enumeração
Provavelmente é melhor executar a função auxiliar, mas quando o tempo é curto, isso fará o trabalho.
fonte
Expandindo as respostas do Prize e do Rune, se você deseja que o atributo value dos itens da sua lista de seleção seja mapeado para o valor inteiro do tipo Enumeração, em vez do valor da string, use o seguinte código:
Em vez de tratar cada valor de enumeração como um objeto TEnum, podemos tratá-lo como um objeto e, em seguida, convertê-lo em número inteiro para obter o valor sem caixa.
Nota: Também adicionei uma restrição de tipo genérico para restringir os tipos para os quais essa extensão está disponível apenas para estruturas (tipo base do Enum) e uma validação de tipo em tempo de execução que garante que a estrutura transmitida seja realmente um Enum.
Atualização 10/23/12: Adicionado parâmetro de tipo genérico para o tipo subjacente e problema corrigido de não compilação que afeta o .NET 4+.
fonte
ToSelectList<TEnum, TEnumValue>(this TEnum enumObj) { ... }
Value = Convert.ToInt32(e)
.(int)e
não compila. :( #Para resolver o problema de obter o número em vez do texto usando o método de extensão do Prise.
fonte
e
paraint
.ID = Convert.ToInt32(e)
.Uma maneira super fácil de fazer isso - sem todo o material de extensão que parece exagero é o seguinte:
Sua enumeração:
Dentro do seu controlador, vincule o Enum a uma lista:
Depois disso, jogue-o em um ViewBag:
Por fim, basta vinculá-lo à View:
Essa é, de longe, a maneira mais fácil que encontrei e não requer extensões nem nada tão louco.
ATUALIZAÇÃO : Veja o comentário de Andrews abaixo.
fonte
Level1 = 1
, o valor da lista suspensa seria em"Level1"
vez de1
.A melhor solução que encontrei para isso foi combinar este blog com a resposta de Simon Goldstone .
Isso permite o uso da enumeração no modelo. Essencialmente, a idéia é usar uma propriedade inteira, bem como a enumeração, e emular a propriedade inteira.
Em seguida, use o atributo [System.ComponentModel.Description] para anotar o modelo com o texto de exibição e use uma extensão "EnumDropDownListFor" em sua exibição.
Isso torna a visualização e o modelo muito legíveis e fáceis de manter.
Modelo:
Visão:
Extensão (diretamente da resposta de Simon Goldstone , incluída aqui para completar):
fonte
Você quer usar algo como
Enum.GetValues
fonte
fonte
Estas são as respostas do Rune & Prêmio alteradas para usar o
int
valor Enum como o ID.Enum de amostra:
Método de extensão:
Amostra de uso:
Lembre-se de importar o espaço para nome que contém o método Extension
Amostra de HTML gerado:
Observe que o item usado para ligar
ToSelectList
é o item selecionado.fonte
Id = Convert.ToInt32(e)
.Esta é a versão do Razor:
fonte
No .NET Core, você pode apenas usar isso:
fonte
<select asp-for="Model.Foo" class="form-control" asp-items="@Html.GetEnumSelectList<MyEnum>()"></select>
.Agora, esse recurso é suportado imediatamente no MVC 5.1 a
@Html.EnumDropDownListFor()
Verifique o seguinte link:
https://docs.microsoft.com/en-us/aspnet/mvc/overview/releases/mvc51-release-notes#Enum
É realmente uma pena que a Microsoft tenha levado 5 anos para implementar um recurso tão procurado de acordo com a votação acima!
fonte
Com base na resposta de Simon, uma abordagem semelhante é fazer com que os valores de Enum sejam exibidos em um arquivo de Recurso, em vez de em um atributo de descrição dentro do próprio Enum. Isso é útil se o seu site precisar ser renderizado em mais de um idioma e se você tiver um arquivo de recurso específico para o Enums, poderá dar um passo adiante e ter apenas valores de Enum no seu Enum e referenciá-los a partir da extensão por uma convenção como [EnumName] _ [EnumValue] - em última análise, menos digitação!
A extensão se parece com:
Recursos no arquivo Enums.Resx parecidos com ItemTypes_Movie: Film
Outra coisa que gosto de fazer é: em vez de chamar o método de extensão diretamente, prefiro chamá-lo com um @ Html.EditorFor (x => x.MyProperty) ou, idealmente, ter apenas o formulário inteiro, em um único @ Html.EditorForModel (). Para fazer isso, altero o modelo da string para ficar assim
Se isso lhe interessa, coloquei uma resposta muito mais detalhada aqui no meu blog:
http://paulthecyclist.com/2013/05/24/enum-dropdown/
fonte
Bem, estou muito atrasado para a festa, mas pelo que vale a pena, escrevi em um blog sobre esse assunto pelo qual crio um
EnumHelper
classe que permite uma transformação muito fácil.http://jnye.co/Posts/4/creating-a-dropdown-list-from-an-enum-in-mvc-and-c%23
No seu controlador:
Na sua opinião:
A classe auxiliar:
fonte
Estou muito atrasado com este, mas encontrei uma maneira muito legal de fazer isso com uma linha de código, se você estiver feliz em adicionar a melodia irrestrita pacote NuGet (uma pequena e agradável biblioteca de Jon Skeet).
Esta solução é melhor porque:
Então, aqui estão as etapas para fazer isso funcionar:
Adicione uma propriedade ao seu modelo da seguinte forma:
Agora que você tem a Lista de SelectListItem exposta no seu modelo, pode usar o @ Html.DropDownList ou @ Html.DropDownListFor usando essa propriedade como fonte.
fonte
Outra correção para esse método de extensão - a versão atual não selecionou o valor atual da enumeração. Eu consertei a última linha:
fonte
Se você deseja adicionar suporte à localização, basta alterar o método s.toString () para algo como isto:
Aqui, o typeof (Resources) é o recurso que você deseja carregar e, em seguida, você obtém a String localizada, também útil se o seu enumerador tiver valores com várias palavras.
fonte
Esta é a minha versão do método auxiliar. Eu uso isso:
Ao invés disso:
Aqui está:
fonte
Você também pode usar meus HtmlHelpers personalizados no Griffin.MvcContrib. O código a seguir:
Gera:
https://github.com/jgauffin/griffin.mvccontrib
fonte
Gostaria de responder a essa pergunta de uma maneira diferente em que o usuário não precisa fazer nada
controller
ouLinq
expressão. Por aqui...eu tenho um
ENUM
Agora eu simplesmente crio um
dropdown
usando issoenum
.OU
Se você deseja selecionar um índice, tente este
Aqui eu usei
AccessLevelEnum.NoAccess
como um parâmetro extra para o padrão, selecionando a lista suspensa.fonte
Encontrei uma resposta aqui . No entanto, algumas das minhas enumerações têm
[Description(...)]
atributo, por isso modifiquei o código para fornecer suporte para isso:Espero que ajude.
fonte
@ Simon Goldstone: Obrigado pela sua solução, ela pode ser perfeitamente aplicada no meu caso. O único problema é que tive que traduzi-lo para o VB. Mas agora está pronto e para economizar tempo de outras pessoas (caso elas precisem), coloquei aqui:
End Você usa assim:
fonte
Acabei criando métodos de extensão para fazer o que é essencialmente a resposta aceita aqui. A última metade do Gist lida com Enum especificamente.
https://gist.github.com/3813767
fonte
fonte
fonte