MVC3 Razor Html.TextBoxFor:我可以像TextAreaFor一样制作多行吗?

时间:2011-07-19 00:05:39

标签: asp.net-mvc-3 textbox razor textarea multiline

我已经看过这篇文章了:Changing the size of Html.TextBox

但是我无法更改为Html.TextAreaFor(),因为它没有设置动态默认值的属性(我正在制作一个编辑页面,我想动态填写当前数据的字段,可以然后被修改)。即使我在viewmodel中更改为[DataType(DataType.MultilineText)],我似乎也无法使EditorFor工作(所有它似乎都改为textboxfor并且我的默认值没有显示)。

我的编辑视图包含一个包含两个模型的视图模型,一个用于填充屏幕字段的空表单(OfferForm)和包含当前数据的offer模型。我想为OfferForm提供文本字段,并使用offer模型数据的内容动态填充它们。

这是我的HTML:

<div class="InLine">
                    <div class="InLine editor-label-container">
                        <div class="editor-label">
                            @Html.LabelFor(model => model.OfferForm.Description)
                        </div>
                    </div>
                    <div class="InLine editor-field-container">
                        <div class="editor-field">
                            @Html.TextBoxFor(model => model.OfferForm.Description, new { @Value = @Html.DisplayFor(model => model.Offer.Description)})
                            @Html.ValidationMessageFor(model => model.Offer.Description)
                        </div>
                    </div>
                </div>
                <div class="InLine">
                    <div class="InLine editor-label-container">
                        <div class="editor-label">
                            @Html.LabelFor(model => model.OfferForm.SMSText)
                        </div>
                    </div>
                    <div class="InLine editor-field-container">
                        <div class="editor-field">
                            @Html.TextBoxFor(model => model.OfferForm.SMSText, new { @Value = @Html.DisplayFor(model => model.Offer.SmsText)})
                            @Html.ValidationMessageFor(model => model.Offer.SmsText)
                        </div>
                    </div>
                </div>

有没有办法在multiline中设置“Html.TextBoxFor()”属性?

2 个答案:

答案 0 :(得分:3)

你必须意识到HTML元素是而不是 windows控件,它们只是稍微映射到它们。

HTML元素必须是跨平台的,并且不能保证textarea只是所有平台上的多行文本框,因此就HTML而言,文本框和文本区域是两个不同的东西。

所以答案是否定的,因为HTML中的文本框没有多行属性。

答案 1 :(得分:2)

最简单的方法是创建一个Html扩展方法,如下所示

public static class HtmlTextAreaExtensions {

    public static IHtmlString TextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, int rows, int cols, object htmlAttributes = null, string Value = null) {
        return TextAreaFor<TModel, TProperty>(htmlHelper, expression, rows, cols, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes), Value);
    }

    public static IHtmlString TextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, int rows, int cols, IDictionary<string, string> htmlAttributes = null, string Value = null) {
        var modelMetadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
        var name = ExpressionHelper.GetExpressionText(expression);

        string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);

        Dictionary<string, object> rowsAndColumns = new Dictionary<string, object>();
        if (rows > 0) {
            rowsAndColumns.Add("rows", rows.ToString(CultureInfo.InvariantCulture));
        } else {
            rowsAndColumns.Add("rows", "5");
        }
        if (cols > 0) {
            rowsAndColumns.Add("cols", cols.ToString(CultureInfo.InvariantCulture));
        } else {
            rowsAndColumns.Add("cols", "20");
        }
        TagBuilder tagBuilder = new TagBuilder("textarea");
        tagBuilder.GenerateId(fullName);
        tagBuilder.MergeAttributes(htmlAttributes, true);
    tagBuilder.MergeAttributes(rowsAndColumns, false);  // Only force explicit rows/cols
        tagBuilder.MergeAttribute("name", fullName, true);

        // If there are any errors for a named field, we add the CSS attribute.
        ModelState modelState;
        if (htmlHelper.ViewData.ModelState.TryGetValue(fullName, out modelState) && modelState.Errors.Count > 0) {
            tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);
        }

        tagBuilder.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(name));

        string value;
        if (Value != null) {
            value = Value;
        } else if (modelState != null && modelState.Value != null) {
            value = modelState.Value.AttemptedValue;
        } else if (modelMetadata.Model != null) {
            value = modelMetadata.Model.ToString();
        } else {
            value = String.Empty;
        }

        // The first newline is always trimmed when a TextArea is rendered, so we add an extra one
        // in case the value being rendered is something like "\r\nHello".
        tagBuilder.SetInnerText(Environment.NewLine + value);

        return new HtmlString(tagBuilder.ToString(TagRenderMode.Normal));
    }
}

然后你可以打电话给它:

@Html.TextAreaFor(f => f.ModelProperty, Value=f.SomeOtherModelProperty)

它只支持基本功能,不支持。实际的标签生成是从Mvc3源中提取的,稍微改变了支持传递值。这应该适用于大多数情况,但您可能需要添加更多覆盖。这不是很干净但是应该让你去。 :)

要让扩展程序显示在您的剃刀视图中,您可以编辑Views目录中的Web.config 并添加命名空间(而不是类名)你放这个班的地方。它应该出现在intellisense中。