2012-06-15 40 views
1

我有稱爲發票,我延伸,用於數據註解的實體DropDownList的和EditorTemplates

[MetadataType(typeof(InvoiceMetadata))] 
    public partial class Invoice 
    { 
     // Note this class has nothing in it. It's just here to add the class-level attribute. 
    } 

    public class InvoiceMetadata 
    { 
     // Name the field the same as EF named the property - "FirstName" for example. 
     // Also, the type needs to match. Basically just redeclare it. 
     // Note that this is a field. I think it can be a property too, but fields definitely should work. 

     [HiddenInput] 
     public int ID { get; set; } 

     [Required] 
     [UIHint("InvoiceType")] 
     [Display(Name = "Invoice Type")] 
     public string Status { get; set; } 


     [DisplayFormat(NullDisplayText = "(null value)")] 
     public Supplier Supplier { get; set; } 

    } 

的Uhint [InvoiceType]導致要加載的InvoiceType編輯模板此element.This模板被定義爲

@model System.String 

@{ 
     IDictionary<string, string> myDictionary = new Dictionary<string, string> { 
                         { "N", "New" } 
                         , { "A", "Approved" }, 
                         {"H","On Hold"} 
                         }; 

     SelectList projecttypes= new SelectList(myDictionary,"Key","Value"); 

     @Html.DropDownListFor(model=>model,projecttypes)  

} 

我在我的程序中有很多這樣的硬編碼狀態列表。我說硬編碼是因爲它們沒有從數據庫中獲取。有沒有其他方法可以爲下拉菜單創建模板?我該如何在模型中聲明一個枚舉,並讓下拉列表加載枚舉而不必將其傳遞給視圖模型?

回答

1

而不是「硬編碼」您的狀態我會創建一個枚舉或Type Safe Enum。對於你的例子,我會使用後者。

對於每一個需要「狀態列表」中創建一個單獨的類與所需的設置:

public sealed class Status 
{ 
    private readonly string _name; 
    private readonly string _value; 

    public static readonly Status New = new Status("N", "New"); 
    public static readonly Status Approved = new Status("A", "Approved"); 
    public static readonly Status OnHold = new Status("H", "On Hold"); 

    private Status(string value, string name) 
    { 
     _name = name; 
     _value = value; 
    } 

    public string GetValue() 
    { 
     return _value; 
    } 

    public override string ToString() 
    { 
     return _name; 
    } 

} 

利用反射現在你可以得到這個類的字段來創建你需要的下拉列表。這將有利於您的項目可以創建一個擴展方法或輔助類:

var type = typeof(Status); 
var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly); 

Dictionary<string, string> dictionary = fields.ToDictionary(
    kvp => ((Status)kvp.GetValue(kvp)).GetValue(), 
    kvp => kvp.GetValue(kvp).ToString() 
    ); 

現在可以創建你的選擇列表就像你正在做:

var list = new SelectList(dictionary,"Key","Value"); 

,這將創造一個用下面的html下拉列表:

<select> 
    <option value="N">New</option> 
    <option value="A">Approved</option> 
    <option value="H">On Hold</option> 
</select> 
+0

如果我要創建一個HTML擴展方法,我應該在模型中聲明狀態類?如果是的話,我必須從HTMLextension(視圖)訪問模型是不是違反規則? – superartsy

+0

這是您的項目將受益於創建「ViewModels」的地方:http://stackoverflow.com/questions/664205/viewmodel-best-practices 在ViewModel中,您可以在其中爲您的狀態創建一個屬性。 – Jesse

+0

我明白ViewModel應該具有作爲屬性的狀態。但是你在哪裏聲明狀態類 - 在模型中?如果是這樣的話 - 擴展方法訪問該類嗎? – superartsy