2010-06-13 11 views
13

Przepraszam, jeśli to jest dup, moje poszukiwania nie przyniosły niczego.Wybrany element na liście rozwijanej z programu Enum w ASP.net MVC

używam następujące metody generowania list rozwijanych dla typów enum (zniesione stąd: http://addinit.com/?q=node/54):

public static string DropDownList(this HtmlHelper helper, string name, Type type, object selected) 
{ 
    if (!type.IsEnum) 
     throw new ArgumentException("Type is not an enum."); 

    if(selected != null && selected.GetType() != type) 
     throw new ArgumentException("Selected object is not " + type.ToString()); 

    var enums = new List<SelectListItem>(); 
    foreach (int value in Enum.GetValues(type)) 
    { 
     var item = new SelectListItem(); 
     item.Value = value.ToString(); 
     item.Text = Enum.GetName(type, value); 

     if(selected != null) 
      item.Selected = (int)selected == value; 

     enums.Add(item); 
    } 

    return System.Web.Mvc.Html.SelectExtensions.DropDownList(helper, name, enums, "--Select--"); 
} 

To działa dobrze, z wyjątkiem jednej rzeczy. Jeśli nadam liście rozwijanej tę samą nazwę, co właściwość w moim modelu, wybrana wartość nie jest ustawiona prawidłowo. Znaczenie to działa:

<%= Html.DropDownList("fam", typeof(EnumFamily), Model.Family)%> 

Ale tego nie robi:

<%= Html.DropDownList("family", typeof(EnumFamily), Model.Family)%> 

Ponieważ staram się przekazać cały obiekt bezpośrednio do metody kontrolera jestem delegowania do Życzyłbym naprawdę jak mieć listę rozwijaną nazwaną dla właściwości w modelu. Gdy używasz nazwy "prawo", menu rozwijane jest wyświetlane poprawnie, po prostu nie mogę ustawić wybranej wartości.

Nie sądzę, to znaczenie, ale używam MVC 1 na mono 2,6

edit: Właśnie to przetestowane na okna i widzę to samo zachowanie

+0

Widziałem to samo zachowanie i pracowałem przy użyciu innej listy rozwijanej o nazwie. – Nate

Odpowiedz

14

Staraj się nie przy użyciu wartości int na enum/zamiast:

item.Value = value.ToString();

zastosowanie:

item.Value = Enum.GetName(type, value);

imo co się dzieje jest że automatycznie ustawia wybraną wartość rozwijanego, aby dopasować model - używając nazwy wyliczeniowej zamiast jej wartości int. Należy pamiętać, że mechanizm przeglądania wyszukuje już wybraną wartość nie tylko w opublikowanej formie (w przypadku, gdy jest już publikowana), ale także w modelu + dane widoku przekazywane do widoku. Tylko wtedy, gdy go tam nie znajdzie, użyje wybranej przez ciebie określonej wartości.

+0

To chyba tylko bilet Freddy'ego - wielkie dzięki. Szkoda, że ​​nie zwiększyłem hojności. Naprawdę myślałem, że to wiązałoby się z wartością wyliczoną, ale dobrze jest w końcu wiedzieć, co się dzieje. Teraz muszę wrócić i cofnąć wszystkie hacki, które ustawiłem na swoim miejscu, więc myślę, że powinienem być na ciebie wściekły;) – AlexCuse

0

To nie robi Wydaje się całkiem słuszny, ale znalazłem, że jeśli nazwę listę rozwijaną z {nameOfInputParameter}. {propertyName} to ładuje ORAZ posty poprawnie. Tak więc, jeśli forma ta została opublikowania sposobu podejmowania parametru tego samego typu jako model formularza o nazwie „myModel” listy rozwijanej dla rodziny może być utworzony tak:

<%= Html.DropDownList("myModel.family", typeof(EnumFamily), Model.Family)%> 

To czyni z identyfikatorem z myModel_family i nazwą myModel.family. Nie jestem pewien, jak się z tym czuć, wydaje mi się to trochę nieprzyjemne. Ale wydaje się, że działa do tej pory. Wprowadza jednak nowy problem. nie można zainicjować otaczaniem, itp ... tak:

<%= Html.TextBox("name") %> 

To będzie ładować wartości poprawnie, ale kiedy piszesz metody kontrolera biorąc „myModel” jako parametr wartości nie są ujmowane jako część przesłanego obiektu. Musimy więc podać nazwę parametru w naszej nazwie wejściowej.

Jednak dodaje nie rozwiąże do wartości, co najmniej za pomocą spoiwa domyślnego modelu (zastanawiam się czy kopanie wokół tam będzie posiadać najlepszą odpowiedź na to pytanie):

<%= Html.TextBox("myModel.name") %> 

Więc trzeba to zrobić:

<%= Html.TextBox("myModel.name", Model.Name) %> 

to wszystko się całkiem brutto (szczególnie na stronach, gdzie muszę być w stanie radzić sobie z sytuacjami, gdzie model jest null).Mam nadzieję, że ktoś ma lepszy pomysł :)

4

Właściwie to jest rozwiązanie. Takie samo rozwiązanie jak moje w tym pytaniu.
ASP.NET MVC - Html.DropDownList - Value not set via ViewData.Model

public static string DropDownList(this HtmlHelper helper, string name, Type type, object selected) 
    { 
     if (!type.IsEnum) 
      throw new ArgumentException("Type is not an enum."); 

     if (selected != null && selected.GetType() != type) 
      throw new ArgumentException("Selected object is not " + type.ToString()); 

     var enums = new List<SelectListItem>(); 
     foreach (int value in Enum.GetValues(type)) 
     { 
      var item = new SelectListItem(); 
      item.Value = value.ToString(); 
      item.Text = Enum.GetName(type, value); 

      if (selected != null) 
       item.Selected = (int)selected == value; 

      enums.Add(item); 
     } 

     // set ViewData first 
     helper.ViewData[name] = enums; 

     // pass in "null" intentionally into the DropDownList extension method 
     return System.Web.Mvc.Html.SelectExtensions.DropDownList(helper, name, null, "--Select--"); 
    } 

Korzystanie item.Value = Enum.GetName(type, value); powoduje spadek <opcji> wartości mają być renderowane jako nazwy Enum dół. Ja osobiście wolę mieć wartości int jako odświeżenie.

Mam nadzieję, że to pomaga.

+0

Interesujące - nie myślałem, żeby używać tego typu danych. Nie jestem pewien, czy w tym momencie chcę przejść tę drogę, ale naprawdę doceniam odpowiedź. Upewnię się, że wypróbuję to, jeśli napotkam jakiekolwiek problemy z obecnym podejściem. – AlexCuse

+0

To była niesamowita odpowiedź, dzięki! – loraderon

+0

To jest niesamowite, szukałem rozwiązania wszędzie – bman

Powiązane problemy