1

問題を説明する適切なタイトルが見つからなかったと思いますが、これが可能な限り短い説明であると思います。

詳細を説明させてください。

@foreachページに自分の写真のリストを表示し、 MVC 3 でループを使用したいと考えています。

このリストの一部を以下に示します。

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

ご存じかもしれませんが、私はリストをこのパーシャルビューに送信しており、写真を 1 つの列に配置しています。

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

任意のガイダンスは非常に高く評価されます。

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

4

1 に答える 1

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="ImageHandler.ashx?id=@picture.value.PicId" 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>

私を悩ませている最後の 1 つのことは、このアンカーです。醜く見えます。そう思わない?スパゲッティコードのようです。

これらの画像をレンダリングするカスタムの再利用可能な HTML ヘルパーを作成して、改善しましょう。

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());
    }
}

そして、表示テンプレートでは、次のようになります。

@model PictureViewModel
@Html.Picture()

そして、それはほとんどそれです。ループを書く必要はありません。すべてが慣習に従って機能します。

于 2011-12-28T15:47:29.357 に答える