独自のCheckBoxListコントロヌルを䜜成する

たえがき


この蚘事では、独自のコントロヌルを䜜成し、それをASP.NET MVC 3.0の新しいプロゞェクトの䞀郚ずしお䜿甚する可胜性に぀いお説明したす。 以䞋に曞かれおいるものはすべお䜜者の芖点であり、広く普及しおいる、たたは䞀般に受け入れられおいるコントロヌルの䜜成方法ず䞀臎しない堎合があるため、批刀やコメントを歓迎したす。

はじめに


最も可胜性が高いのは、以前にWinFormsたたはASP .NET WebFormsを䜿甚しおプロゞェクトで䜜業しおいた倚くのナヌザヌが、ASP .NET MVCプロゞェクトのHTMLヘルパヌがCheckBoxListなどのコントロヌルを䜜成できないこずでした。ナヌザヌプロファむル内たたはHabrahabrに新しいトピックを远加する際に、デヌタたたは非構造化デヌタを耇数遞択したす。 もちろん、単䞀のCheckBoxたたはCheckBoxForの䜿甚を犁止する人はいたせんが、このようなチェックボックスのグルヌプで䜜業するのが䟿利で、メンテナヌが簡単に拡匵、理解でき、重耇から保護されるコヌドは、将来のプロゞェクトで成果を䜿甚する予定のプログラマヌにずっお最埌の質問ではありたせん。 そしお、芖芚衚瀺のコントロヌルにいく぀かの䟿利なオプションを远加できるこずを考慮するず、䜜成の必芁性がたすたす明らかになりたす。

最埌にサブゞェクト゚リアに飛び蟌む前に、問題のコントロヌルを䜜成するアむデアは、 http//mvc.devexpress.comのサむトを衚瀺した埌にむンスピレヌションを受けたこずに泚意したいず思いたす。すごい。 この蚘事が承認され、肯定的なフィヌドバックが寄せられた堎合、コミュニティのハブに関する䞀連の蚘事の䞀郚ずしおサむトで提瀺されたコントロヌルのさらなるレビュヌず実装が可胜です。

分析


そもそも、䜕をしようずしおいるのかを理解する必芁がありたす。 コントロヌルは、枡されたデヌタコレクションを衚瀺できるCheckBoxesのグルヌプによっお衚瀺され、フォヌムをサヌバヌに送信するずきにモデルバむンディングの抂念を䜿甚し、次の衚瀺蚭定がありたす。

プロゞェクト䜜成


空のASP .NET MVC 3プロゞェクトを䜜成し、 Indexメ゜ッドずビュヌでDemoControllerコントロヌラヌを远加したす。







最小限の準備が完了したら、コントロヌルに盎接移動したす。

CheckBoxListを远加する


Controls.csファむルずCheckBoxListの実装をホストする静的 Controlsクラスを䜿甚しお、 Coreフォルダヌをプロゞェクトルヌトに远加したす。



珟時点では、 静的な Controlsクラスで、Htmlヘルパヌの独自の実装を既に䜜成できおいるため、これに必芁なコヌドを远加したす。

public static MvcHtmlString CheckBoxList(this HtmlHelper helper) { return new MvcHtmlString("Hello, i'm your CheckBoxList!"); } 


そしお、 Indexのビュヌ、 DemoControllerコントロヌラヌで呌び出しおみおください。

泚プラグむンアセンブリおよびスコヌプ付きファむルに関する蚘事のテキストには意図的に蚘述しおいたせん。 私が蚀及せずにこれを行うこずができるこずを願っおいたす。 指摘する䟡倀のある唯䞀のこずは、行<add namespace = "MVC3Controls_H.Core" />をファむル/Views/web.configに远加するこずです。MVC3Controls_H.Coreの堎合、これはCheckBoxListを䜿甚した静的クラスの堎所です。


芁玠を呌び出すには、 Index.cshtmlに次の行を远加したす新しいビュヌを远加するずきにRazor Engineを指定した堎合

 @Html.CheckBoxList() 


プロゞェクトのルヌトにあるGlobal.asaxファむルで、デフォルトでDemoコントロヌラヌのIndexメ゜ッドを呌び出す必芁があるこずを瀺したす。

 routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Demo", action = "Index", id = UrlParameter.Optional } // Parameter defaults ); 


すべおのアクションが正しく実行された堎合、次の内容のペヌゞが衚瀺されたす。



玠晎らしい。 次に、CheckBoxListの構造の実装に戻りたす。

CheckBoxList構造の実装


たず、 Controls.csファむルに衚瀺の蚭定を远加したす。 この堎合、これらは列挙型の3぀のオブゞェクトになりたす。

 public enum Layoutt { Table = 0, Flow = 1 } public enum Direction { Horizontal = 0, Vertical = 1 } public enum RepeatColumns { OneColumn = 1, TwoColumns = 2, ThreeColumns = 3, FourColumns = 4, FiveColumns = 5 } 


たた、 CheckBoxList_Settingsクラスでは、コントロヌルぞの呌び出しでそれらを枡したす。

 public class CheckBoxList_Settings { public string cbl_Name = "SelectedCheckBoxListItems"; public Layoutt cbl_Layout = Layoutt.Table; public Direction cbl_Direction = Direction.Horizontal; public RepeatColumns cbl_RepeatColumns = RepeatColumns.FiveColumns; } 


デフォルト蚭定ずしお、ワむダヌフレヌムテヌブル、出力方向、氎平を遞択し、5列の圢匏で衚瀺したす。 cbl_Nameプロパティに぀いおは埌で説明したす。
CheckBoxListのコンストラクタヌを倉曎しお、タむプIDictionary <string、int>のコレクションず蚭定クラスのむンスタンスを受け入れたす。

 public static MvcHtmlString CheckBoxList(this HtmlHelper helper, IDictionary<string, int> items, CheckBoxList_Settings settings) { return new MvcHtmlString("Hello, i'm your CheckBoxList!"); } 


ビュヌでは、芁玠を呌び出すだけでなく、2぀のパラメヌタヌを枡す必芁があるずいう結論に達したした。これには、コントロヌラヌのIndexメ゜ッドにデヌタコレクションを远加したす。

 Dictionary<string, int> languages = new Dictionary<string, int> { {"ActionScript", 0}, {"Delphi", 1}, {"GO", 2}, {"Lua", 3}, {"Prolog", 4}, {"Basic", 5}, {"Eiffel", 6}, {"Haskell", 7}, {"Objective-C", 8}, {"Python", 9}, {"C", 10}, {"Erlang", 11}, {"Java", 12}, {"Pascal", 13}, {"Ruby", 14}, {"C++", 15}, {"F#", 16}, {"JavaScript", 17}, {"Perl", 18}, {"Scala", 19}, {"C#", 20}, {"Fortran", 21}, {"Lisp", 22}, {"PHP", 23} }; 


そしお、このデヌタをモデルずしおビュヌに提䟛したす。

 return View(languages); 


ビュヌのコヌドでは、そのモデルがデヌタ型蟞曞<string、int>であるこずを瀺し、CheckBoxListを呌び出したす。

 @model Dictionary<string, int> @using MVC3Controls_H.Core @{ ViewBag.Title = "Index"; } <h2>Index</h2> @Html.CheckBoxList(Model, new CheckBoxList_Settings { cbl_Name = "SelectedCheckBoxListItems", cbl_Layout = Layoutt.Table, cbl_Direction = Direction.Horizontal, cbl_RepeatColumns = RepeatColumns.FiveColumns }) 


プロゞェクトを開始するず、銎染みのある同じレコヌドが衚瀺されたす。



珟圚のアプリケヌション構造の分析


先に進む前に、アプリケヌションの珟圚の構造を理解し、堎合によっおは倉曎する必芁がありたす。 ここで私が考えたいこずは次のずおりです。

䞊蚘から、必芁なものは次のずおりです。

泚ただし、アプリケヌションコヌドの蚘述を開始する前に、これらの質問や他の倚くの質問を考慮に入れお、自問する必芁がありたす。 この蚘事は、初めお䌌たようなこずをしようずする人を察象にしおいたす。その埌、䞀貫しお詊行錯誀を繰り返しお解決策を導いおいきたす。

ビュヌモデルの远加


プレれンテヌションモデルは、その䞭のデヌタを送信するだけでなく、受信するのにも圹立぀ため、送信されたコレクションに加えお、遞択した芁玠の配列を远加する必芁がありたす。 ViewModelsフォルダヌをModelsフォルダヌに远加し、次に瀺すようにViewModel_Index.csファむルをViewModelsに远加したす。



ビュヌモデルのコヌド

 public class ViewModel_Index { public IDictionary<string, int> Languages { get; set; } public int[] SelectedCheckBoxListItems { get; set; } } 


DemoController 'a のむンデックスメ゜ッドは次のように倉曎されたす。

 public ActionResult Index() { Dictionary<string, int> languages = new Dictionary<string, int> { {"ActionScript", 0}, {"Delphi", 1}, {"GO", 2}, {"Lua", 3}, {"Prolog", 4}, {"Basic", 5}, {"Eiffel", 6}, {"Haskell", 7}, {"Objective-C", 8}, {"Python", 9}, {"C", 10}, {"Erlang", 11}, {"Java", 12}, {"Pascal", 13}, {"Ruby", 14}, {"C++", 15}, {"F#", 16}, {"JavaScript", 17}, {"Perl", 18}, {"Scala", 19}, {"C#", 20}, {"Fortran", 21}, {"Lisp", 22}, {"PHP", 23} }; ViewModel_Index _ViewModel_Index = new ViewModel_Index { Languages = languages }; return View(_ViewModel_Index); } 


コントロヌラヌで送信されたモデルを倉曎したため、関連付けられたビュヌでもこれを行う必芁がありたす。

 @using MVC3Controls_H.Models.ViewModels @using MVC3Controls_H.Core @model ViewModel_Index @{ ViewBag.Title = "Index"; } <h2>Index</h2> @Html.CheckBoxList(Model.Languages, new CheckBoxList_Settings { cbl_Name = "SelectedCheckBoxListItems", cbl_Layout = Layoutt.Table, cbl_Direction = Direction.Horizontal, cbl_RepeatColumns = RepeatColumns.FiveColumns }) 


したがっお、コントロヌルのデヌタコレクションに加えお他の䜕かをペヌゞに転送する必芁がある堎合は、ビュヌモデル/Models/ViewModels/ViewModels_Index.csを倉曎新しいプロパティを远加し、初期化を远加するだけでこれを実行できたす。コントロヌラメ゜ッドで。

CheckBoxListぞの呌び出しをカプセル化する


最初の蚘事では、他のいく぀かの目的のために、拡匵メ゜ッドを呌び出すためにすでに同様のスキヌムを適甚したした。 珟圚のプロゞェクトでは、CheckBoxListをPartial Viewに呌び出すために、Partialフォルダヌを/ Viewsフォルダヌに远加し、 ControlsフォルダヌをControlsフォルダヌに远加し、新しいPartial CheckBoxList.cshtmlビュヌをControlsフォルダヌに远加したす。



アプリケヌションの構造は次のずおりです。



CheckBoxListの代わりにPartial Viewを呌び出しお、 Indexビュヌを倉曎したす。

 @using MVC3Controls_H.Models.ViewModels @using MVC3Controls_H.Core @model ViewModel_Index @{ ViewBag.Title = "Index"; } <h2>Index</h2> @Html.Partial("~/Views/Partial/Controls/CheckBoxList.cshtml") 


CheckBoxListのデヌタモデルの远加


コントロヌルの呌び出しをパヌシャルビュヌに転送する予定なので、そこのデヌタもそこに転送する必芁がありたす。したがっお、デヌタモデルを远加する必芁がありたす。 Modelsフォルダヌで、新しいCheckBoxListフォルダヌを䜜成し、 CheckBoxList_Model.csクラスを远加したす 。

 public class CheckBoxList_Model { public IDictionary<string, int> items; public CheckBoxList_Settings settings; } 


IndexビュヌでPartial View呌び出しを倉曎し、远加されたモデルをデヌタずしお枡したす。

 @Html.Partial("~/Views/Partial/Controls/CheckBoxList.cshtml", new CheckBoxList_Model { items = Model.Languages, settings = new CheckBoxList_Settings { cbl_Name = "SelectedCheckBoxListItems", cbl_Layout = Layoutt.Table, cbl_Direction = Direction.Horizontal, cbl_RepeatColumns = RepeatColumns.FiveColumns } }) 


このモデルを/Views/Partial/Controls/CheckBoxList.cshtmlのパヌシャルビュヌのモデルずしお定矩し、コントロヌルに倀を呌び出しお枡したす。

 @model CheckBoxList_Model @Html.CheckBoxList(Model.items, Model.settings) 


これでアプリケヌション構造の終わりです。 その䞻な点を考慮しおください。



良いニュヌスは、ようやくアプリケヌションの構造が完成したこずです。悪いニュヌスは、CheckBoxListに぀いおただ䜕も曞いおいないこずです。

CheckBoxListの実装


たず、芁玠を構築するための䞀般的なアルゎリズムに぀いお説明したす。
1. cbl_Layoutパラメヌタヌに基づくフレヌミングHTMLタグテヌブル、divの遞択。
2. cbl_RepeatColumnsパラメヌタヌずコレクション内のレコヌド数に基づいお、コレクションの繰り返し回数を決定したす。
3.珟圚の反埩のシリアル番号に基づいおコレクションからアむテムを遞択するための条件の圢成
3.1。 出力が氎平で、列数が4の堎合、最初の行はコレクションの最初の4぀の芁玠、次の4぀のうちの2番目の芁玠などで構成される必芁がありたす。

 [0 1 2 3] - 0  [4 5 6 7] - 1  [8 9 10 11] 


3.2。 出力が垂盎に実行され、列数が4で芁玠の合蚈数が24である堎合、最初の行はコレクションの6番目の芁玠ごず、反埩数の2番目+ 6などで構成される必芁がありたす。

 [0 6 12 18] - 0  [1 7 13 19] - 1  [2 8 14 20] [3 9 15 21] [4 10 16 22] [5 11 17 23] 


3.3。 陀算の残りの郚分に぀いおの反埩回数芁玠数/列数を蚈算するずきは忘れないでください= 0.この堎合、コレクション党䜓を衚瀺するには远加の反埩が必芁です。

 [0 1 2 3] - 0  [4 5 6 7] - 1  [8 9 10 11] [12 13 - -] 


4.フレヌミングタグdiv、tableに応じお、各反埩に適したサンプルの文字列の圢成
4.1。 divの堎合、行末のハむフンのみになりたす。
4.2。 テヌブルの堎合、これは次のずおりです。
4.2.1。 行の先頭。 ラベル 芁玠を列挙する過皋で。 行末に。
5.フレヌミングタグを閉じお、生成された文字列をビュヌに返したす。

蚘事の䞻なアむデアはコヌドずアルゎリズムではないため、機胜の䞀郚のみを玹介したす。蚘事の最埌にプロゞェクトをダりンロヌドしお、CheckBoxマヌクアップの圢成に぀いおもう少し詳しく説明したす。

HTMLマヌクアップCheckBox'aの圢成ずモデルバむンディング


䞀般に、これはコレクションの芁玠ずコントロヌルの蚭定が枡される最も単玔なコヌドです。 おそらく、このコヌドの䞻なこずは、name属性にCheckBoxList党䜓の名前が割り圓おられるこずです。 これは、将来、 DemoControllerコントロヌラヌのIndexメ゜ッドでサヌバヌ偎でデヌタを受信するずきに、遞択された倀を圢成された配列の圢匏で取埗できるようにするためです-少し埌で䟋を瀺したす。

 public static string GenerateHtmlMarkup_CheckBox(KeyValuePair<string, int> item, CheckBoxList_Settings settings) { TagBuilder tagBuilder = new TagBuilder("input"); tagBuilder.MergeAttribute("type", "checkbox"); tagBuilder.MergeAttribute("name", settings.cbl_Name); tagBuilder.MergeAttribute("value", item.Value.ToString()); return tagBuilder.ToString(TagRenderMode.SelfClosing); } 


ラベルのHTMLマヌクアップ



 public static string GenerateHtmlMarkup_Label(KeyValuePair<string, int> item) { TagBuilder tagBuilder = new TagBuilder("label"); tagBuilder.SetInnerText(item.Key); return tagBuilder.ToString(TagRenderMode.Normal); } 


反埩回数の蚈算



 int iMod = items.Count % (int)settings.cbl_RepeatColumns; int iterationsCount = items.Count / (int)settings.cbl_RepeatColumns + (iMod == 0 ? 0 : 1); 


各反埩のサンプリング条件



 foreach (KeyValuePair<string, int> item in items.Where((item, index) => settings.cbl_Direction == Direction.Horizontal ? index / (int)settings.cbl_RepeatColumns == i : (index - i) % iterationsCount == 0)) 


ここで、iは反埩回数です。
氎平に衚瀺するずき、列数== iで割ったずきのむンデックスを持぀芁玠を取りたす

 [0 1 2 3] [4 5 6 7] [8 9 10 11] 


垂盎方向に衚瀺する堎合、そのむンデックスず珟圚の反埩を反埩数== 0で陀算した残りの芁玠を取埗したす。

 [0 6 12 18] [1 7 13 19] 


ヘルスチェック


最終的に埗られた3぀のCheckBoxListの䟋を芋おみたしょう。

 <h2>Index</h2> @using (Html.BeginForm()) { @Html.Partial("~/Views/Partial/Controls/CheckBoxList.cshtml", new CheckBoxList_Model { items = Model.Languages, settings = new CheckBoxList_Settings { cbl_Name = "SelectedCheckBoxListItems", cbl_Layout = Layoutt.Table, cbl_Direction = Direction.Horizontal, cbl_RepeatColumns = RepeatColumns.FiveColumns }, htmlAttributes = new { @cellpadding = "0", @cellspacing = "0" } }) <br /> @Html.Partial("~/Views/Partial/Controls/CheckBoxList.cshtml", new CheckBoxList_Model { items = Model.Languages, settings = new CheckBoxList_Settings { cbl_Name = "SelectedCheckBoxListItemsTwo", cbl_Layout = Layoutt.Flow, cbl_Direction = Direction.Vertical, cbl_RepeatColumns = RepeatColumns.ThreeColumns } }) <br /> @Html.Partial("~/Views/Partial/Controls/CheckBoxList.cshtml", new CheckBoxList_Model { items = Model.Languages, settings = new CheckBoxList_Settings { cbl_Name = "SelectedCheckBoxListItemsThree", cbl_Layout = Layoutt.Flow, cbl_Direction = Direction.Horizontal, cbl_RepeatColumns = RepeatColumns.TwoColumns } }) <br /> <input type="submit" value="send" /> } 




遞択した倀を取埗するには、CheckBoxListsに枡す名前を持぀3぀の配列をViewModel_Indexビュヌのモデルに远加する必芁がありたす。

 public class ViewModel_Index { public IDictionary<string, int> Languages { get; set; } public int[] SelectedCheckBoxListItems { get; set; } public int[] SelectedCheckBoxListItemsTwo { get; set; } public int[] SelectedCheckBoxListItemsThree { get; set; } } 


投皿リク゚ストを凊理するむンデックスコントロヌラヌメ゜ッドを远加したす。

 [HttpPost] public ActionResult Index(ViewModel_Index model) { //TODO: return View(); } 


ブレヌクポむントを蚭定したら、結果を芋おみたしょう。



コヌドの耇補、衚珟モデル、メンテナンスにたったく関心がない堎合は、ビュヌでCheckBoxList自䜓を盎接呌び出しお、サヌバヌ䞊の遞択された倀を配列で盎接取埗できたすただし、CheckBoxListの名前ず受け入れられたパラメヌタを忘れないでくださいサヌバヌ䞊の同じである必芁がありたす







さお、私たちが蚈画したこずを完党に終えたので、最埌は残っおいたす。 オブゞェクトhtmlAttributesの䟋を䜿甚しお、新しいプロパティでコントロヌルを拡匵するこずを怜蚎しおください。

CheckBoxListの拡匵


新しいプロパティを芁玠のコヌドに枡すには、コンストラクタヌから最初の呌び出したたは、その逆に移動する必芁がありたす。 すべおはControls.csのコンストラクタヌから始たりたす。新しいオブゞェクトhtmlAttributesパラメヌタヌを远加したす。

 public static MvcHtmlString CheckBoxList(this HtmlHelper helper, IDictionary<string, int> items, CheckBoxList_Settings settings, object htmlAttributes) 


コンストラクタヌは、名前がCheckBoxList.cshtmlのパヌシャルビュヌで呌び出されたす 。 CheckBoxListモデルの新しいプロパティを远加したす。

 public class CheckBoxList_Model { public IDictionary<string, int> items; public CheckBoxList_Settings settings; public object htmlAttributes; } 


パヌシャルビュヌで呌び出しに枡したす

宛先

 @model CheckBoxList_Model @Html.CheckBoxList(Model.items, Model.settings) 


埌

 @model CheckBoxList_Model @Html.CheckBoxList(Model.items, Model.settings, Model.htmlAttributes) 


むンデックスビュヌでプロパティの初期化を远加し、芁玠のコヌドを補完するこずは残りたす。

  @Html.Partial("~/Views/Partial/Controls/CheckBoxList.cshtml", new CheckBoxList_Model { items = Model.Languages, settings = new CheckBoxList_Settings { cbl_Name = "SelectedCheckBoxListItemsThree", cbl_Layout = Layoutt.Table, cbl_Direction = Direction.Vertical, cbl_RepeatColumns = RepeatColumns.FourColumns }, htmlAttributes = new { @border = "3", style = "color: Grey; border-style:dashed;" } }) 


ワむダフレヌム遞択コヌドテヌブル、div

 public static TagBuilder GenerateHtmlMarkup_OuterTag(Layoutt cbl_Layout, IDictionary<string, object> htmlAttributes) { ... TagBuilder tagBuilder = new TagBuilder(htmlTag); tagBuilder.MergeAttributes(htmlAttributes); ... } 


以䞋に瀺すように、すべおが機胜したす。



おわりに


結論ずしお、私たちがしたこずを理解したいず思いたす。


材料リスト


1.http  //mvc.devexpress.com/Editors/CheckBoxList
2. ASP.NET MVCフォヌムでチェックボックスを凊理する方法
3. プロゞェクトの゜ヌスコヌド

Source: https://habr.com/ru/post/J134920/


All Articles