EditorFor()およびhtmlプロパティ
-
06-07-2019 - |
質問
Asp.Net MVC 2.0プレビュービルドは、次のようなヘルパーを提供します
Html.EditorFor(c => c.propertyname)
プロパティ名が文字列の場合、上記のコードはtexboxをレンダリングします。
MaxLengthおよびSizeプロパティをテキストボックスまたは独自のcssクラスプロパティに渡したい場合はどうなりますか
アプリケーションのサイズと長さの組み合わせごとに1つのテンプレートを作成する必要がありますか?その場合、デフォルトのテンプレートは使用可能になりません。
解決 11
自分の質問に答えるためにブログエントリを作成しました
他のヒント
MVC3では、次のように幅を設定できます。
@Html.TextBoxFor(c => c.PropertyName, new { style = "width: 500px;" })
これを解決するには、/ Views / Shared / EditorTemplatesフォルダーにString.ascxという名前のEditorTemplateを作成します。
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %>
<% int size = 10;
int maxLength = 100;
if (ViewData["size"] != null)
{
size = (int)ViewData["size"];
}
if (ViewData["maxLength"] != null)
{
maxLength = (int)ViewData["maxLength"];
}
%>
<%= Html.TextBox("", Model, new { Size=size, MaxLength=maxLength }) %>
私の見解では、私は使用しています
<%= Html.EditorFor(model => model.SomeStringToBeEdited, new { size = 15, maxLength = 10 }) %>
私にとって魅力のように動作します!
@ Html.EditorForのHTML属性の設定に関するこのスレッドまたは他のスレッドの回答はどれも、私にとって大いに助けになりました。しかし、私は
で素晴らしい答えを見つけました同じアプローチを使用しましたが、多くの余分なコードを記述しなくても美しく機能しました。 Html.EditorForのhtml出力のid属性が設定されていることに注意してください。ビューコード
<style type="text/css">
#dob
{
width:6em;
}
</style>
@using (Html.BeginForm())
{
Enter date:
@Html.EditorFor(m => m.DateOfBirth, null, "dob", null)
}
データ注釈と日付フォーマットが<!> quot; dd MMM yyyy <!> quot;
のモデルプロパティ[Required(ErrorMessage= "Date of birth is required")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd MMM yyyy}")]
public DateTime DateOfBirth { get; set; }
余分なコードを大量に記述することなく、魅力のように機能しました。この回答では、ASP.NET MVC 3 Razor C#を使用しています。
Kiran Chandのブログ投稿では、ビューモデルで次のようなカスタムメタデータを使用しています。
[HtmlProperties(Size = 5, MaxLength = 10)]
public string Title { get; set; }
これは、メタデータを利用するカスタムテンプレートと組み合わされます。私の意見ではきれいでシンプルなアプローチですが、mvcに組み込まれているこの一般的なユースケースを見たいと思います。
<!> quot; additionalViewData <!> quot;で渡すことについて誰も言及していないことに驚いています。反対側で読みます。
表示(わかりやすくするために改行あり):
<%= Html.EditorFor(c => c.propertyname, new
{
htmlAttributes = new
{
@class = "myClass"
}
}
)%>
エディターテンプレート:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %>
<%= Html.TextBox("", Model, ViewData["htmlAttributes"])) %>
問題は、テンプレートに複数のHTML要素を含めることができるため、MVCはサイズ/クラスをどの要素に適用するかを認識できないことです。自分で定義する必要があります。
TextBoxViewModelと呼ばれる独自のクラスからテンプレートを派生させます:
public class TextBoxViewModel
{
public string Value { get; set; }
IDictionary<string, object> moreAttributes;
public TextBoxViewModel(string value, IDictionary<string, object> moreAttributes)
{
// set class properties here
}
public string GetAttributesString()
{
return string.Join(" ", moreAttributes.Select(x => x.Key + "='" + x.Value + "'").ToArray()); // don't forget to encode
}
}
テンプレートでこれを行うことができます:
<input value="<%= Model.Value %>" <%= Model.GetAttributesString() %> />
あなたの意見では:
<%= Html.EditorFor(x => x.StringValue) %>
or
<%= Html.EditorFor(x => new TextBoxViewModel(x.StringValue, new IDictionary<string, object> { {'class', 'myclass'}, {'size', 15}}) %>
最初のフォームは、文字列のデフォルトのテンプレートをレンダリングします。 2番目のフォームは、カスタムテンプレートをレンダリングします。
代替構文は流れるようなインターフェースを使用します:
public class TextBoxViewModel
{
public string Value { get; set; }
IDictionary<string, object> moreAttributes;
public TextBoxViewModel(string value, IDictionary<string, object> moreAttributes)
{
// set class properties here
moreAttributes = new Dictionary<string, object>();
}
public TextBoxViewModel Attr(string name, object value)
{
moreAttributes[name] = value;
return this;
}
}
// and in the view
<%= Html.EditorFor(x => new TextBoxViewModel(x.StringValue).Attr("class", "myclass").Attr("size", 15) %>
ビューでこれを行う代わりに、コントローラーでこれを行うことも、ViewModelで行うこともできます。
public ActionResult Action()
{
// now you can Html.EditorFor(x => x.StringValue) and it will pick attributes
return View(new { StringValue = new TextBoxViewModel(x.StringValue).Attr("class", "myclass").Attr("size", 15) });
}
また、すべてのビューテンプレートの共通基盤であるベースTemplateViewModelクラスを作成できることに注意してください。これには、属性などの基本的なサポートが含まれます。
しかし、一般的にはMVC v2にはもっと良い解決策が必要だと思います。まだベータ版です-お願いします;-)
CSSを使用することが道だと思います。 XAMLのように、.NETコーディングでもっとできるといいのですが、ブラウザではCSSが重要です。
Site.css
#account-note-input {
width:1000px;
height:100px;
}
.cshtml
<div class="editor-label">
@Html.LabelFor(model => model.Note)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Note, null, "account-note-input", null)
@Html.ValidationMessageFor(model => model.Note)
</div>
ジョー
MVC 5の場合と同様に、属性を追加する場合は単純に実行できます
@Html.EditorFor(m => m.Name, new { htmlAttributes = new { @required = "true", @anotherAttribute = "whatever" } })
からの情報 プロパティの属性を定義できます。
[StringLength(100)]
public string Body { get; set; }
これはSystem.ComponentModel.DataAnnotations
として知られています。
必要なValidationAttribute
が見つからない場合は、常にカスタム属性を定義できます。
よろしく、 カルロス
これは最も洗練されたソリューションではないかもしれませんが、簡単です。 HtmlHelper.EditorForクラスに拡張機能を作成できます。その拡張機能では、ヘルパーのViewDataにオプションを書き込むオプションパラメーターを指定できます。コードを次に示します。
最初に、拡張メソッド:
public static MvcHtmlString EditorFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, TemplateOptions options)
{
return helper.EditorFor(expression, options.TemplateName, new
{
cssClass = options.CssClass
});
}
次に、オプションオブジェクト:
public class TemplateOptions
{
public string TemplateName { get; set; }
public string CssClass { get; set; }
// other properties for info you'd like to pass to your templates,
// and by using an options object, you avoid method overload bloat.
}
そして最後に、String.ascxテンプレートの行を次に示します。
<%= Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { @class = ViewData["cssClass"] ?? "" }) %>
率直に言って、これはあなたのコードを将来にわたって維持しなければならない貧しい人々にとっては簡単で明白だと思います。また、テンプレートに渡す他のさまざまな情報にも簡単に拡張できます。これまでのところ、周囲のhtmlを標準化するために一連のテンプレートでできる限りラップしようとしているプロジェクトで、私にとってはうまく機能しています。 http://bradwilson.typepad.com/blog/2009/10/ aspnet-mvc-2-templates-part-5-master-page-templates.html 。
Html.EditorForで動作しない理由はわかりませんが、TextBoxForを試してみましたが、動作しました。
@Html.TextBoxFor(m => m.Name, new { Class = "className", Size = "40"})
...そして検証も動作します。
実際には、HtmlHelperが1つだけのEditorTemplatesを使用するのが最適であることがわかりました。ほとんどの場合はTextBoxです。より複雑なhtml構造のテンプレートが必要な場合は、別のHtmlHelperを作成します。
TextBoxのhtmlAttributesの代わりにViewDataオブジェクト全体を固定できることを考えます。さらに、特別な処理が必要な場合は、ViewDataの一部のプロパティのカスタマイズコードを作成できます。
@model DateTime?
@*
1) applies class datepicker to the input;
2) applies additionalViewData object to the attributes of the input
3) applies property "format" to the format of the input date.
*@
@{
if (ViewData["class"] != null) { ViewData["class"] += " datepicker"; }
else { ViewData["class"] = " datepicker"; }
string format = "MM/dd/yyyy";
if (ViewData["format"] != null)
{
format = ViewData["format"].ToString();
ViewData.Remove("format");
}
}
@Html.TextBox("", (Model.HasValue ? Model.Value.ToString(format) : string.Empty), ViewData)
ビューの構文と出力されたhtmlの例を以下に示します。
@Html.EditorFor(m => m.Date)
<input class="datepicker" data-val="true" data-val-required="&#39;Date&#39; must not be empty." id="Date" name="Date" type="text" value="01/08/2012">
@Html.EditorFor(m => m.Date, new { @class = "myClass", @format = "M/dd" })
<input class="myClass datepicker" data-val="true" data-val-required="&#39;Date&#39; must not be empty." id="Date" name="Date" type="text" value="1/08">
質問は EditorFor に対するものであるため、TextBoxFor WEFXの提案は機能しません。
個々の入力ボックスを変更するには、EditorForメソッドの出力を処理できます。
<%: new HtmlString(Html.EditorFor(m=>m.propertyname).ToString().Replace("class=\"text-box single-line\"", "class=\"text-box single-line my500pxWideClass\"")) %>
MVCがEditorForテキストボックスのクラスを .text-box で設定するため、すべてのEditorForsを変更することもできます。したがって、スタイルシートまたはページ。
.text-box {
width: 80em;
}
さらに、次のスタイルを設定できます
input[type="text"] {
width: 200px;
}
- これは.text-boxをオーバーライドし、すべての入力テキストボックス、EditorForなどを変更します。
また、MVC3でTextBoxの幅を設定する際に問題がありましたが、Clsss属性の設定はTextAreaコントロールでは機能しましたが、TextBoxForコントロールまたはEditorForコントロールでは機能しませんでした
<!> ampをフォローしようとしました。それは私のために働いた:
@ Html.TextBoxFor(model = <!> gt; model.Title、new {Class = <!> quot; textBox <!> quot ;, style = <!> quot; width:90%; <!> quot;} )
この場合も検証は完全に機能しています。
これを回避する方法の1つは、ビューモデルにデリゲートを配置して、このような特別なレンダリングの印刷を処理することです。これをページングクラスに対して実行し、モデルのパブリックプロパティを公開してFunc<int, string> RenderUrl
処理します。
したがって、カスタムビットの記述方法を定義します。
Model.Paging.RenderUrl = (page) => { return string.Concat(@"/foo/", page); };
Paging
クラスのビューを出力します:
@Html.DisplayFor(m => m.Paging)
...および実際の<=>ビューの場合:
@model Paging
@if (Model.Pages > 1)
{
<ul class="paging">
@for (int page = 1; page <= Model.Pages; page++)
{
<li><a href="@Model.RenderUrl(page)">@page</a></li>
}
</ul>
}
それは複雑すぎる問題と見なされる可能性がありますが、私はこれらのページャーをいたるところで使用しており、同じ定型コードが表示されるのを我慢できませんでした。
UPDATE:hm、モデルは値によって渡されるため、属性は保持されないため、明らかにこれは機能しません。しかし、私はこの答えをアイデアとして残します。
別の解決策は、独自のTextBox / etcヘルパーを追加して、モデルの独自の属性をチェックすることだと思います。
public class ViewModel
{
[MyAddAttribute("class", "myclass")]
public string StringValue { get; set; }
}
public class MyExtensions
{
public static IDictionary<string, object> GetMyAttributes(object model)
{
// kind of prototype code...
return model.GetType().GetCustomAttributes(typeof(MyAddAttribute)).OfType<MyAddAttribute>().ToDictionary(
x => x.Name, x => x.Value);
}
}
<!-- in the template -->
<%= Html.TextBox("Name", Model, MyExtensions.GetMyAttributes(Model)) %>
これは簡単ですが、それほど便利/柔軟ではありません。
これは、ここで解決策を得るための最もクリーンでエレガントでシンプルな方法です。
見事なブログ投稿で、狂った教授のようなカスタム拡張機能/ヘルパーメソッドを書くのは面倒です。
http:// geekswithblogs.net/michelotti/archive/2010/02/05/mvc-2-editor-template-with-datetime.aspx
/ Views / Shared / EditorTemplatesフォルダーにあるString.ascxというEditorTemplateを使用する@tjeerdansの回答が本当に好きでした。これは、この質問に対する最も簡単な答えのようです。ただし、Razor構文を使用したテンプレートが必要でした。さらに、MVC3はデフォルトとしてStringテンプレートを使用しているようです(StackOverflowの質問<!> quot; 文字列のmvc表示テンプレートが整数に使用される <!> quot;)モデルを文字列ではなくオブジェクトに設定します。私のテンプレートはこれまでのところ機能しているようです:
@model object
@{ int size = 10; int maxLength = 100; }
@if (ViewData["size"] != null) {
Int32.TryParse((string)ViewData["size"], out size);
}
@if (ViewData["maxLength"] != null) {
Int32.TryParse((string)ViewData["maxLength"], out maxLength);
}
@Html.TextBox("", Model, new { Size = size, MaxLength = maxLength})
解決しました!!
Razorの構文は次のとおりです。
@Html.TextAreaFor(m=>m.Address, new { style="Width:174px" })
これは、テキスト領域の幅を、styleパラメーターで定義した幅に調整します。
ASPxの構文は次のとおりです。
<%=Html.TextAreaFor(m => m.Description, new { cols = "20", rows = "15", style="Width:174px" })%>
これでうまくいきます