1

私は自分の問題を説明するのに適切なタイトルを見つけることができなかったと信じていますが、これは可能な限り短い説明です。複数の列を持つコンテナにIEnumerableシーケンスをバインドするにはどうすればよいですか?

詳細を教えてください。

私はページ上の私の写真の一覧を表示し、

にMVC 3の上に以下のように、このリストの部分図を@foreachループを使用したい:

@model IEnumerable<Picture> 
@foreach (var item in Model) 
{ 
    <a href="@item.PicId"> 
     <img height="35px" style="padding-top:3px" src="[email protected]" id="pictureMy" /> 
    </a> 
} 

あなたは私は理解しているようこの部分ビューにリストを送信し、ピクチャを単一の列に配置しています。

問題なく動作していますが、1行につき3枚の写真を表示したいのに、管理できませんでした。

ご指摘いただければ幸いです。

ご協力いただきありがとうございます。

答えて

6

あなたは可能性が3でグループにそれらを:

@model IEnumerable<Picture> 
@foreach (var item in Model.Select((value, index) => new { value, index }).GroupBy(x => x.index/3)) 
{ 
    <div> 
    @foreach (var picture in item) 
    { 
     <a href="@picture.value.PicId"> 
      <img height="35px" style="padding-top:3px" src="[email protected]" id="pictureMy" /> 
     </a> 
    } 
    </div> 
} 

しかし、正直なところ、このグループ分けは、ビューに行われるべきものではありません。ビューモデルを定義し、コントローラアクションでグループ化を実行してビューモデルを返す必要があります。

それでは、我々の見解モデルを定義することから始めてみましょう:その後、

public class PictureViewModel 
{ 
    public int PicId { get; set; } 
} 

public class GroupedPicturesViewModel 
{ 
    public IEnumerable<PictureViewModel> Pictures { get; set; } 
} 

コントローラのアクション:

public ActionResult Index() 
{ 
    // fetch the pictures from the DAL or something 
    IEnumerable<Picture> pictures = ... 

    // Now build the view model 
    var model = pictures 
     .Select((value, index) => new { value, index }) 
     .GroupBy(x => x.index/3) 
     .Select(x => new GroupedPicturesViewModel 
     { 
      Pictures = x.Select(p => new PictureViewModel 
      { 
       PicId = p.value.PicId 
      }) 
     } 
    ); 
    return View(model); 
} 

、対応するビュー:

@model IEnumerable<GroupedPicturesViewModel> 
@Html.DisplayForModel() 

ため、対応する表示テンプレートGroupedPicturesViewModelタイプ(~/Views/Shared/DisplayTemplates/GroupedPicturesViewModel.cshtml):

@model GroupedPicturesViewModel 
<div> 
    @Html.DisplayFor(x => x.Pictures) 
</div> 

PictureViewModelタイプ(~/Views/Shared/DisplayTemplates/PictureViewModel.cshtml)のために、最後に表示テンプレート:私を悩ませています

@model PictureViewModel 
<a href="@Model.PicId"> 
    <img class="image" src="@Url.Content("~/ImageHandler.ashx?id=" + Model.PicId)" alt="" /> 
</a> 

最後にもう一つの事は、このアンカーです。見苦しい。あなたは思いませんか?スパゲッティコードのように見えます。かなりのだ

@model PictureViewModel 
@Html.Picture() 

をそしてそれ:

public static class HtmlExtensions 
{ 
    public static IHtmlString Picture(this HtmlHelper<PictureViewModel> htmlHelper) 
    { 
     var anchor = new TagBuilder("a"); 
     var picture = htmlHelper.ViewData.Model; 
     var id = picture.PicId.ToString(); 
     var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext); 

     // You probably need another property on your view model here as this 
     // id is suspicious about href but since that's what you had in your 
     // original code I don't know what is your intent. 
     anchor.Attributes["href"] = id; 
     var image = new TagBuilder("img"); 
     image.Attributes["alt"] = ""; 
     image.Attributes["src"] = urlHelper.Content(
      "~/ImageHandler.ashx?id=" + urlHelper.Encode(id) 
     ); 
     image.AddCssClass("image"); 
     anchor.InnerHtml = image.ToString(); 
     return new HtmlString(anchor.ToString()); 
    } 
} 

、その後、表示テンプレートに、我々は単純になります:

のは、これらの写真をレンダリングするカスタム、再利用可能なHTMLヘルパーを書き込むことによって、それを改善してみましょうそれ。ループを書く必要はありません。すべてが慣例に従って動作します。

+0

それは魅力のように機能します!ダーリンありがとうございました:) – MrGorki

+0

本当にエキサイティングです!私はあなたの提案を確実に実行するつもりです。もう一度ありがとう! – MrGorki

+0

私が本当に助けてくれたので、もう一度ダーリンに感謝したいと思います。 .Select((value、index)=> new {value、index}) .GroupBy(x => x.index/3) .Select(x)を選択すると、画像をはっきりと理解するためにもう1つ質問があります。 =>新しいGroupedPicturesViewModel { 写真= x.Selectた(p =>新しいPictureViewModel { PicId = p.value.PicId }) } アプローチ。このクエリの数を制限するための任意のチャンスはありますか?同様にのみランダムな順序で6個のPCを表示します。 – MrGorki

関連する問題