我目前正在使用View中的以下代码来调整Html.TextAreaFor()的高度以适应其内容。是否有更好的& /或更简洁的方法来做到这一点?
...
int width = 85;
int lines = 1;
string[] arr = Model.Text.Split(new string[] {"\r\n", "\n", "\r"}, StringSplitOptions.None);
foreach (var str in arr)
{
if (str.Length / width > 0)
{
lines += str.Length / width + (str.Length % width <= width/2 ? 1 : 0);
}
else
{
lines++;
}
}
@Html.TextAreaFor(m => m.Text,
new
{
id = "text",
style = "width:" + width + "em; height:" + lines + "em;"
})
...
答案 0 :(得分:5)
代码看起来很好。一种可能的改进是将其外部化为可重用的帮助程序,以避免污染视图:
public static class TextAreaExtensions
{
public static IHtmlString TextAreaAutoSizeFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
object htmlAttributes
)
{
var model = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).Model;
var text = model as string ?? string.Empty;
int width = 85;
int lines = 1;
string[] arr = text.Split(new string[] { "\r\n", "\n", "\r" }, StringSplitOptions.None);
foreach (var str in arr)
{
if (str.Length / width > 0)
{
lines += str.Length / width + (str.Length % width <= width / 2 ? 1 : 0);
}
else
{
lines++;
}
}
var attributes = new RouteValueDictionary(htmlAttributes);
attributes["style"] = string.Format("width:{0}em; height:{1}em;", width, lines);
return htmlHelper.TextAreaFor(expression, attributes);
}
}
并在视图中:
@Html.TextAreaAutoSizeFor(m => m.Text, new { id = "text" })
答案 1 :(得分:3)
看起来很棒, 您也可以使用JQuery autogrow textarea plugin。
它可以为您节省一些编码,甚至可能更有效。
答案 2 :(得分:2)
你可以用一些LINQ魔法将它减少到一行:
var lines = Model.Text.Split( new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None )
.Aggregate( 0, (total, next) =>
total += next.Length <= width ? 1
: (int)Math.Ceiling( (double)next.Length / width ) );
请注意,您的分割方式存在一个小问题。如果输入中确实存在混合\n
,\r
和\r\n
行结尾(不太可能),则此拆分将按从左到右的顺序拆分,因此不会拆分在字符串\r\n
上,这意味着\r
和\n
之间的空行。所以你会看到我将\r\n
移动为拆分中的第一个字符串。