使用一个for循环渲染一个TreeView [英] Render a treeview using a for-loop
问题描述
我在这个类:
公共类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;
< DIV>
@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>
}
< DIV 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)< DIV 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(/)< DIV 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屋!