2010-09-14 58 views
8

Tôi có một enum cho một trong các thuộc tính của mô hình xem của tôi. Tôi muốn hiển thị một danh sách thả xuống chứa tất cả các giá trị của enum. Tôi có thể làm điều này để làm việc với mã sau đây.Làm cách nào để điền danh sách thả xuống có giá trị enum?

Điều tôi thắc mắc là liệu có cách đơn giản để chuyển đổi từ một enum sang IEnumerable? Tôi có thể làm điều đó theo cách thủ công như trong ví dụ sau, nhưng khi tôi thêm một giá trị enum mới, mã sẽ bị ngắt. Tôi tưởng tượng rằng tôi có thể làm điều đó thông qua sự phản ánh theo điều này example, nhưng có cách nào khác để làm điều này?

public enum Currencies 
{ 
    CAD, USD, EUR 
} 

public ViewModel 
{ 
    [Required] 
    public Currencies SelectedCurrency {get; set;} 

    public SelectList Currencies 
    { 
    List<Currencies> c = new List<Currencies>(); 
    c.Add(Currencies.CAD); 
    c.Add(Currencies.USD); 
    c.Add(Currencies.EUR); 

    return new SelectList(c); 
    } 
} 

Trả lời

18

Tôi đang sử dụng một helper mà tôi tìm thấy here để cư SelectLists của tôi với một kiểu enum chung chung, tôi đã làm một điều chỉnh nhỏ để thêm giá trị được chọn mặc dù, dưới đây là cách hiển thị:

public static SelectList ToSelectList<T>(this T enumeration, string selected) 
{ 
    var source = Enum.GetValues(typeof(T)); 

    var items = new Dictionary<object, string>(); 

    var displayAttributeType = typeof(DisplayAttribute); 

    foreach (var value in source) 
    { 
     FieldInfo field = value.GetType().GetField(value.ToString()); 

     DisplayAttribute attrs = (DisplayAttribute)field. 
         GetCustomAttributes(displayAttributeType, false).FirstOrDefault() 

     items.Add(value, attrs != null ? attrs.GetName() : value.ToString()); 
    } 

    return new SelectList(items, "Key", "Value", selected); 
} 

Điều thú vị là nó đọc DisplayAttribute làm tiêu đề thay vì tên enum. (Nếu enums của bạn chứa khoảng trắng hoặc bạn cần nội địa hóa sau đó nó làm cho cuộc sống của bạn dễ dàng hơn nhiều)

Vì vậy, bạn sẽ cần phải thêm attirubete Display enums của bạn như thế này:

public enum User_Status 
{ 
    [Display(Name = "Waiting Activation")] 
    Pending, // User Account Is Pending. Can Login/Can't participate 

    [Display(Name = "Activated")] 
    Active,    // User Account Is Active. Can Logon 

    [Display(Name = "Disabled")] 
    Disabled,   // User Account Is Diabled. Can't Login 
} 

và đây là cách bạn sử dụng chúng trong quan điểm của bạn.

<%: Html.DropDownList("ChangeStatus" , ListExtensions.ToSelectList(Model.statusType, user.Status))%> 

Model.statusType chỉ là đối tượng enum loại User_Status.

Vậy đó, không còn SelectLists nào trong Chế độ xem của bạn nữa. Trong ví dụ của tôi, tôi đang sắp xếp một enum trong ViewModel nhưng bạn có thể refrence enum type trực tiếp trong view của bạn. Tôi chỉ làm nó để làm cho mọi thứ sạch sẽ và tốt đẹp.

Hy vọng điều đó hữu ích.

+0

Giải pháp tuyệt vời! –

+3

Giải pháp tuyệt vời thực sự. Tuy nhiên, nếu mục nhập trong enum không có thuộc tính mô tả, nó không thành công. Vì vậy, thay thế '.First()' bằng '.FirstOrDefault()' và thay vì 'items.Add (giá trị, attrs.GetName());' có 'items.Add (giá trị, attrs! = Null? Attrs.GetName (): value.ToString()); 'Điều đó giúp bạn nhập vào Mô tả cho các mục Enum rõ ràng. – trailmax

+0

được thực hiện, cảm ơn bạn đã sửa chữa. –

2

Nhìn vào Enum.GetNames (typeof (Đơn vị tiền tệ))

1

Vì vậy, nhiều câu trả lời tốt - Tôi nghĩ I'sd thêm giải pháp của tôi - Tôi đang xây dựng SelectList trong giao diện (và không có trong Controller):

Trong c của tôi #:

namespace ControlChart.Models 
//My Enum 
public enum FilterType { 
[Display(Name = "Reportable")]  
Reportable = 0,  
[Display(Name = "Non-Reportable")]  
NonReportable,  
[Display(Name = "All")]  
All }; 

//My model: 
public class ChartModel { 
[DisplayName("Filter")] 
public FilterType Filter { get; set; } 
} 

Trong cshtml tôi:

@using System.ComponentModel.DataAnnotations 
@using ControlChart.Models 
@model ChartMode 
@*..........*@ 
@Html.DropDownListFor(x => x.Filter,       
from v in (ControlChart.Models.FilterType[])(Enum.GetValues(typeof(ControlChart.Models.FilterType))) 
select new SelectListItem() { 
    Text = ((DisplayAttribute)(typeof(FilterType).GetField(v.ToString()).GetCustomAttributes(typeof(DisplayAttribute), false).First())).Name,        
    Value = v.ToString(),        
    Selected = v == Model.Filter       
    }) 

HTH

1

tôi rất muộn một ngày này nhưng tôi chỉ tìm thấy một wa thực sự mát mẻ y để làm điều này với một dòng mã, nếu bạn vui lòng thêm gói Unconstrained Melody NuGet (một thư viện nhỏ, đẹp từ Jon Skeet).

Giải pháp này là tốt hơn bởi vì:

  1. Nó đảm bảo (với các ràng buộc kiểu chung chung) mà giá trị thực sự là một giá trị enum (do Unconstrained Melody)
  2. Nó tránh đấm bốc không cần thiết (do Unconstrained Melody)
  3. Nó lưu trữ tất cả các mô tả để tránh sử dụng sự phản chiếu trên mọi cuộc gọi (do Giai điệu không bị giới hạn)
  4. Nó ít mã hơn các giải pháp khác!

Vì vậy, sau đây là các bước để làm việc này:

  1. Trong Package Manager Console, "Install-Package UnconstrainedMelody"
  2. Thêm một tài sản trên mô hình của bạn như sau:

    //Replace "YourEnum" with the type of your enum 
    public IEnumerable<SelectListItem> AllItems 
    { 
        get 
        { 
         return Enums.GetValues<YourEnum>().Select(enumValue => new SelectListItem { Value = enumValue.ToString(), Text = enumValue.GetDescription() }); 
        } 
    } 
    

Bây giờ bạn có Danh sách SelectListItem được hiển thị trên mẫu của mình, bạn có thể sử dụng @ Html.DropDownList hoặc @ Html.DropDownListFor sử dụng thuộc tính này làm nguồn.

0

Có thể đã quá muộn, nhưng tôi nghĩ nó có thể hữu ích cho những người có cùng vấn đề. Tôi đã tìm thấy here rằng bây giờ với MVC 5, nó bao gồm một trình trợ giúp EnumDropDownListFor html làm cho không còn cần thiết việc sử dụng trình trợ giúp tùy chỉnh hoặc cách giải quyết khác.

Trong trường hợp này, chỉ cần thêm này:

@Html.EnumDropDownListFor(x => x.SelectedCurrency) 

và đó là tất cả!

Bạn cũng có thể dịch hoặc thay đổi nội dung hiển thị thông qua các chú thích dữ liệu và các tập tin nguồn:

  1. Thêm các chú thích số liệu sau đây để enum của bạn:

    public enum Currencies 
    { 
        [Display(Name="Currencies_CAD", ResourceType=typeof(Resources.Enums)] 
        CAD, 
        [Display(Name="Currencies_USD", ResourceType=typeof(Resources.Enums)]  
        USD, 
        [Display(Name="Currencies_EUR", ResourceType=typeof(Resources.Enums)] 
        EUR 
    } 
    
  2. Tạo tập tin nguồn lực tương ứng.

Các vấn đề liên quan