使用一个for循环渲染一个TreeView [英] Render a treeview using a for-loop

查看:198
本文介绍了使用一个for循环渲染一个TreeView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这个类:

 公共类SortOrderModel
{
    公共字符串IDSORT {搞定;组; }
    公开名单< ContentPage>内容网页{搞定;组; }
}

这有listpropery上面的类是这个类的一个列表:

 公共类ContentPage
{
公共字符串ID {搞定;组; }
公共字符串ParentReference {搞定;组; }
公共字符串名称{搞定;组; }
公共字符串SortOrder的{搞定;组; }
}

和我们说我在SortOrderModel作为发送到@model视图。

和视图:Model.ContentPages,是5 ContentPage与值的列表:

  VAR家=新ContentPage()
{
    ID =内容网页/ 1,
    标题=家,
    ParentReference =/,
    SortOrder的=0
};VAR约=新ContentPage()
{
    ID =内容网页/ 2,
    标题=关于,
    ParentReference =内容网页/ 1,
    SortOrder的=1
};VAR CONTACTINFO =新ContentPage()
{
    ID =内容网页/ 3,
    标题=的ContactInfo
    ParentReference =内容网页/ 2,
    SortOrder的=0
};VAR allProducts =新ContentPage()
{
    ID =内容网页/ 4,
    标题=AllProducts
    ParentReference =内容网页/ 1,
    SortOrder的=2
};VAR产品1 =新ContentPage()
{
    ID =内容网页/ 5,
    标题=产品1,
    ParentReference =内容网页/ 4,
    SortOrder的=0
};    VAR产品2 =新ContentPage()
{
    ID =内容网页/ 6,
    标题=产品1,
    ParentReference =内容网页/ 4,
    SortOrder的=1
};

我怎样才能使这些值树形视图使用一个for循环,所以它看起来像这样的:

 >家
    >关于
        >的ContactInfo
    > AllProducts
        >产品1
        >产品2

这是非常重要的是使用一个for循环,因为我要去使用它在一个视图与@ Html.TextBoxFor为SortOrder的-属性,所以我可以改变每个对象的中将sortOrder值。而据我所知,我需要使用一个for循环,而不是一个foreach得到模型结合的工作,因为我送的值,以一个[HttpPost] -method。

这是我试图做到这一点:

  @model CMS_Affiliate_Web.Models.SortOrderModel
@ {
字符串startPageId =;
的foreach(在Model.ContentPages.Where VAR PAGEID(O => o.Url ==/\").Select(o => o.Id))
{
    startPageId = PAGEID;
}
}
< UL>
    <立GT;
        < D​​IV>
            @using(Html.BeginForm(SortOrderMenu,安全,Model.ContentPages,FormMethod.Post))
        {
            @ Html.HiddenFor(O => Model.IdSort)            变种内容网页= Model.ContentPages.ToList();
            的for(int i = 0; I< contentPages.Count();我++)
            {
                < UL>                    @if(Model.ContentPages [I]的.url ==/|| Model.ContentPages [I] .ParentReference == startPageId)
                    {
                        <立GT; @ Model.ContentPages [I] .title伪@ Html.TextBoxFor(O => Model.ContentPages [I] .SortOrder,新{@class =sortBox})LT; /李>
                    }
                    否则,如果(contentPages.Any(M = GT; m.Id ==内容网页,[我] .ParentReference))
                    {
                        <李风格=填充左:80px;颜色:红色;> @ Model.ContentPages [I] .title伪@ Html.TextBoxFor(O => Model.ContentPages [I] .SortOrder,新{@class =sortBox})LT; /李>
                    }
                < / UL>
            }
            < D​​IV CLASS =活动,台>
                <输入类型=提交值=Spara纽约sortering级=BTN BTN-主要NAME =saveSliders/>
            < / DIV>
        }
    < / DIV>
< /李>

但它使得它这个样子,不是我想要的:

 >家
    >关于
    > AllProducts
        >产品1
        >产品2
        >的ContactInfo

编辑!

  @model Models.SortOrderModel@ {
ViewBag.Title =SortOrderMenu;
布局=〜/查看/共享/ _Layout.cshtml
}
@helper RenderItems(字符串的parentID,INT缩进= 0)
{
@ Html.HiddenFor(O => Model.IdSort)
INT指数= ViewBag.ItemIndex? 0;
在Model.ContentPages的foreach(VAR contentPage
    。凡(P => p.ParentReference ==的parentID)
    .OrderBy(P => p.SortOrder))
{
    <李风格=填充左:@(缩进)像素;颜色:红色;>
        @ Html.TextBoxFor(O => Model.ContentPages [指数] .ID)
        @ contentPage.Title
        @ Html.TextBoxFor(O => Model.ContentPages [指数] .SortOrder,
            新{@class =sortBox})
    < /李>
    ViewBag.ItemIndex = ++指数;
    @RenderItems(contentPage.Id,缩进+ 20)
    ;
    指数= ViewBag.ItemIndex;
}
}@using(Html.BeginForm(SortOrderMenu,安全,Model.ContentPages,FormMethod.Post))
{
@RenderItems(内容网页/ 6401)< D​​IV CLASS =活动,台>
    <输入类型=提交值=Spara纽约sortering级=BTN BTN-主要NAME =saveSliders/>
< / DIV>
}

编辑2 ---------------

  @helper RenderItems(字符串的parentID,INT缩进= 0)
{
@ Html.HiddenFor(O => Model.IdSort)
INT指数= ViewBag.ItemIndex? 0;
在Model.ContentPages的foreach(VAR contentPage
                                 。凡(P => p.ParentReference ==的parentID)
                                 .OrderBy(P => p.SortOrder))
{    <李风格=填充左:@(缩进)像素;颜色:红色;>
        @ Html.TextBoxFor(O => Model.ContentPages [指数] .ID)
        @ contentPage.Title
        @ Html.TextBoxFor(O => Model.ContentPages [指数] .SortOrder,
                                 新{@class =sortBox})
    < /李>
    ViewBag.ItemIndex = ++指数;
    @RenderItems(contentPage.Id,缩进+ 20);
                                           指数= ViewBag.ItemIndex;
}
}@using(Html.BeginForm(SortOrderMenu,安全,Model.ContentPages,FormMethod.Post))
{
@RenderItems(/)< D​​IV CLASS =活动,台>
    <输入类型=提交值=Spara纽约sortering级=BTN BTN-主要NAME =saveSliders/>
< / DIV>
}

ControllerMethods:

  [HTTPGET]
    公众的ActionResult SortOrderMenu()
    {
        VAR allContentPages = RavenSession.Query< ContentPage>()了ToList()。        VAR sortOrderModel =新SortOrderModel();
        sortOrderModel.ContentPages = allContentPages;
        返回查看(sortOrderModel);
    }    [HttpPost]
    公众的ActionResult SortOrderMenu(SortOrderModel模型)
    {
        的foreach(在model.ContentPages VAR页)
        {
            VAR contPage = RavenSession.Load< ContentPage>(page.Id);            contPage.SortOrder = page.SortOrder;
            RavenSession.SaveChanges();
        }        返回RedirectToAction(SortOrderMenu);
    }


解决方案

您最终会与下面的递归帮助:

  @helper RenderItems(字符串的parentID,INT缩进= 0)
{
    在Model.ContentPages的foreach(VAR contentPage
                                     。凡(P => p.ParentReference ==的parentID)
                                     .OrderBy(P => p.SortOrder))
    {
        VAR指数= Model.ContentPages.IndexOf(contentPage);
        <李风格=填充左:@(缩进)像素;颜色:红色;>
            @ Html.TextBoxFor(O => Model.ContentPages [指数] .ID)
            @ contentPage.Title
            @ Html.TextBoxFor(O => Model.ContentPages [指数] .SortOrder,
                新{@class =sortBox})
        < /李>
        @RenderItems(contentPage.Id,缩进+ 20)
    }
}

有关使用只是把它在你的看法是这样的:

  @RenderItems(/);

编辑:
另外,您可以使用隐藏的输入与Model.ContentPages.Index作为名称定义索引:

  @helper RenderItems(字符串的parentID,INT缩进= 0)
{
    在Model.ContentPages的foreach(VAR contentPage
                                     。凡(P => p.ParentReference ==的parentID)
                                     .OrderBy(P => p.SortOrder))
    {
        VAR指数= Guid.NewGuid();
        <输入类型=隐藏的名字=Model.ContentPages.IndexVALUE =@(指数)/>
        <李风格=填充左:@(缩进)像素;颜色:红色;>
            @ contentPage.Title
            <输入类型=文本级=sortBox
                   NAME =Model.ContentPages [@(指数)。SortOrder的
                   值=@ contentPage.SortOrder/>
        < /李>
        @RenderItems(contentPage.Id,缩进+ 20)
    }
}

关于它的菲尔哈克的更多细节伟大的博客文章集合结合

I'm having this class:

public class SortOrderModel
{
    public string IdSort { get; set; }
    public List<ContentPage> ContentPages { get; set; }
}

The above class that have the listpropery is a list of this class:

public class ContentPage
{
public string Id { get; set; }
public string ParentReference { get; set; }
public string Title { get; set; }
public string SortOrder { get; set; }
}

And let's say I'm sending in SortOrderModel as @model to a view.

And in the view: Model.ContentPages, is a List of 5 ContentPage with the values:

var home = new ContentPage()
{
    Id = "ContentPages/1",
    Title = "Home",
    ParentReference = "/",
    SortOrder = "0"
};

var about = new ContentPage()
{
    Id = "ContentPages/2",
    Title = "About",
    ParentReference = "ContentPages/1",
    SortOrder = "1"
};

var contactinfo = new ContentPage()
{
    Id = "ContentPages/3",
    Title = "ContactInfo",
    ParentReference = "ContentPages/2",
    SortOrder = "0"
};

var allProducts = new ContentPage()
{
    Id = "ContentPages/4",
    Title = "AllProducts",
    ParentReference = "ContentPages/1",
    SortOrder = "2"
};

var product1 = new ContentPage()
{
    Id = "ContentPages/5",
    Title = "Product1",
    ParentReference = "ContentPages/4",
    SortOrder = "0"
};

    var product2 = new ContentPage()
{
    Id = "ContentPages/6",
    Title = "Product1",
    ParentReference = "ContentPages/4",
    SortOrder = "1"
};

How can I render a treeview with these values using a for-loop, so it looks like something like this:

> Home
    > About
        > ContactInfo
    > AllProducts
        > Product1
        > Product2

It's very important to use a for-loop, because I'm gonna use it in a view with @Html.TextBoxFor for the SortOrder-Properties so I can change the sortOrder values of each object. And as far as I know I need to use a for-loop and not a foreach to get the model-binding to work, because i'm sending the values to a [HttpPost]-method.

This is my attempt to do it:

@model CMS_Affiliate_Web.Models.SortOrderModel
@{
string startPageId = "";
foreach (var pageId in Model.ContentPages.Where(o => o.Url == "/").Select(o => o.Id))
{
    startPageId = pageId;
}
}
<ul>
    <li>
        <div>
            @using (Html.BeginForm("SortOrderMenu", "secure", Model.ContentPages, FormMethod.Post))
        {
            @Html.HiddenFor(o => Model.IdSort)

            var contentPages = Model.ContentPages.ToList();
            for (int i = 0; i < contentPages.Count(); i++)
            {
                <ul>

                    @if (Model.ContentPages[i].Url == "/" || Model.ContentPages[i].ParentReference == startPageId)
                    {
                        <li>@Model.ContentPages[i].Title @Html.TextBoxFor(o => Model.ContentPages[i].SortOrder, new {@class = "sortBox"})</li>
                    }
                    else if (contentPages.Any(m => m.Id == contentPages[i].ParentReference))
                    {
                        <li style="padding-left: 80px; color: red;">@Model.ContentPages[i].Title @Html.TextBoxFor(o => Model.ContentPages[i].SortOrder, new {@class = "sortBox"})</li>
                    }
                </ul>
            }
            <div class="activity-desk">
                <input type="submit" value="Spara ny sortering" class="btn btn-primary" name="saveSliders" />
            </div>
        }
    </div>
</li>

But it renders it like this, not what I want:

> Home
    > About
    > AllProducts
        > Product1
        > Product2
        > ContactInfo

EDIT!

@model Models.SortOrderModel

@{
ViewBag.Title = "SortOrderMenu";
Layout = "~/Views/Shared/_Layout.cshtml";
}


@helper RenderItems(string parentID, int indent = 0)
{
@Html.HiddenFor(o => Model.IdSort)
int index = ViewBag.ItemIndex ?? 0;
foreach (var contentPage in Model.ContentPages
    .Where(p => p.ParentReference == parentID)
    .OrderBy(p => p.SortOrder))
{
    <li style="padding-left: @(indent)px; color: red;">
        @Html.TextBoxFor(o => Model.ContentPages[index].Id)
        @contentPage.Title
        @Html.TextBoxFor(o => Model.ContentPages[index].SortOrder,
            new {@class = "sortBox"})
    </li>
    ViewBag.ItemIndex = ++index;
    @RenderItems(contentPage.Id, indent + 20)
    ;
    index = ViewBag.ItemIndex;
}
}

@using (Html.BeginForm("SortOrderMenu", "secure", Model.ContentPages, FormMethod.Post))
{
@RenderItems("ContentPages/6401")

<div class="activity-desk">
    <input type="submit" value="Spara ny sortering" class="btn btn-primary" name="saveSliders"    />
</div>
}

EDIT 2 ---------------

@helper RenderItems(string parentID, int indent = 0)
{
@Html.HiddenFor(o => Model.IdSort)
int index = ViewBag.ItemIndex ?? 0;
foreach (var contentPage in Model.ContentPages
                                 .Where(p => p.ParentReference == parentID)
                                 .OrderBy(p => p.SortOrder))
{

    <li style="padding-left: @(indent)px; color: red;">
        @Html.TextBoxFor(o => Model.ContentPages[index].Id)
        @contentPage.Title
        @Html.TextBoxFor(o => Model.ContentPages[index].SortOrder,
                                 new { @class = "sortBox" })
    </li>
    ViewBag.ItemIndex = ++index;
    @RenderItems(contentPage.Id, indent + 20);
                                           index = ViewBag.ItemIndex;
}
}

@using (Html.BeginForm("SortOrderMenu", "secure", Model.ContentPages, FormMethod.Post))
{
@RenderItems("/")

<div class="activity-desk">
    <input type="submit" value="Spara ny sortering" class="btn btn-primary" name="saveSliders" />
</div>
}

ControllerMethods:

[HttpGet]
    public ActionResult SortOrderMenu()
    {
        var allContentPages = RavenSession.Query<ContentPage>().ToList();

        var sortOrderModel = new SortOrderModel();
        sortOrderModel.ContentPages = allContentPages;


        return View(sortOrderModel);
    }

    [HttpPost]
    public ActionResult SortOrderMenu(SortOrderModel model)
    {
        foreach (var page in model.ContentPages)
        {
            var contPage = RavenSession.Load<ContentPage>(page.Id);

            contPage.SortOrder = page.SortOrder;
            RavenSession.SaveChanges();
        }

        return RedirectToAction("SortOrderMenu");
    }

解决方案

You would end up with following recursive helper:

@helper RenderItems(string parentID, int indent = 0)
{
    foreach (var contentPage in Model.ContentPages
                                     .Where(p => p.ParentReference == parentID)
                                     .OrderBy(p => p.SortOrder))
    {
        var index = Model.ContentPages.IndexOf(contentPage);
        <li style="padding-left: @(indent)px; color: red;">
            @Html.TextBoxFor(o => Model.ContentPages[index].Id)
            @contentPage.Title
            @Html.TextBoxFor(o => Model.ContentPages[index].SortOrder,
                new { @class = "sortBox" })
        </li>
        @RenderItems(contentPage.Id, indent + 20)
    }
}

For usage just call it on your view like this:

@RenderItems("/");

EDIT: Alternatively you could use hidden input with Model.ContentPages.Index as name for defining your index:

@helper  RenderItems(string parentID, int indent = 0)
{
    foreach (var contentPage in Model.ContentPages
                                     .Where(p => p.ParentReference == parentID)
                                     .OrderBy(p => p.SortOrder))
    {
        var index = Guid.NewGuid();
        <input type="hidden" name="Model.ContentPages.Index" value="@(index)" />
        <li style="padding-left: @(indent)px; color: red;">
            @contentPage.Title 
            <input type="text" class="sortBox" 
                   name="Model.ContentPages[@(index)].SortOrder" 
                   value="@contentPage.SortOrder" />
        </li>
        @RenderItems(contentPage.Id, indent + 20)
    }
}

More details about it in Phil Haack's great blog post about collection binding

这篇关于使用一个for循环渲染一个TreeView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆