2012-06-15 78 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