2014-06-17 32 views
2

我有很多表单遵循Label:Control的通用格式。我决定,而不是页面如下:EditorTemplates和ViewData

<div class="row-fluid"> 
    <div class="span4"> 
     @Html.LabelFor(m => m.Prop1) 
    </div> 
    <div class="span8"> 
     @Html.TextBoxFor(m => m.Prop1) 
    </div> 
</div> 

我会创建一个编辑器模板来保存这种模式,并选择正确的默认控制。当然,队友马上指出,对跨度进行硬编码并没有帮助,所以我添加了一些自定义的ViewData字段,例如“labelSpan”。

的真正的问题是这样的:

@Html.TextBoxFor(m => m, new { @class = @ViewData["class"], style = @ViewData["style"], 
id = @ViewData["id"]... etc }) 

所以问题1:如何巩固通过直接而不必指定每个属性?

问题2:如何以下列方式不冲突?

@Html.LabelFor(m => m, new { @class = @ViewData["LabelClass"], style = @ViewData["LabelStyle"] }) 

回答

0

比使用ViewData相反,你需要使用ModelMetadata。如果您创建自定义ModelMetadataProvider,则可以覆盖CreateMetadata方法以将相应的值添加到AdditionalAttributes,然后您可以稍后查询这些值。

protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, 
                Type containerType, Func<object> modelAccessor, 
                Type modelType, string propertyName) 
    { 
     var metadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName); 
     var labelSpan = "span4"; // do whatever logic you need to. 
     metadata.AdditionalValues.Add("labelSpan", labelSpan); 
     ... 
     return metadata; 
    } 

然后,在编辑器模板中使用元数据。我找到工作的模式是只把标签在你Object.cshtml编辑模板:

@{ 
    var visibleProperties = ViewData.ModelMetadata.Properties.Where(pm => pm.ShowForEdit && !ViewData.TemplateInfo.Visited(pm)).ToList(); 
    var noHtmlProps = visibleProperties.Where(pm => pm.HideSurroundingHtml).ToList(); 
    var normalProperties = visibleProperties.Where(pm => !pm.HideSurroundingHtml).ToList(); 
    foreach (var prop in normalProperties) 
    { 
     <div class="row-fluid"> 
      @Html.Label(prop.PropertyName, prop.DisplayName, 
       new{@class=ViewData.ModelMetadata.AdditionalValues["labelSpan"]}) 

      @(prop.IsReadOnly 
       ? Html.Display(prop.PropertyName) 
       : Html.Editor(prop.PropertyName)) 
      @Html.ValidationMessage(prop.PropertyName) 
     </div> 
    } 
    // Output hidden properties at the end 
    foreach (var prop in noHtmlProps) 
    { 
     @Html.Editor(prop.PropertyName) 
    } 
} 

然后您使用其它类型的编辑模板,以确定哪个控制使用。例如,String.cshtml可能如下所示:

@Html.TextBox(string.Empty, ViewData.TemplateInfo.FormattedModelValue, 
    new{@class = ViewData.ModelMetadata.AdditionalValues["valueSpan"]})