使用LINQ为Repeater构建分层导航

时间:2011-04-06 09:58:10

标签: c# asp.net linq repeater

我正在尝试从CMS输出分层导航列表,如下所示:

YEAR
- MONTH
- - ARTICLE 1
- - ARTICLE 2

该页面是模板化的,因此如果您在年份页面上,您将看到:

MONTH
- ARTICLE 1
- ARTICLE 2

显然,如果您在月份页面上,您只会看到指向文章的链接

我正在尝试构建一个LINQ查询来处理逻辑,然后在DataTable中构建它以由Repeater处理。我真的很难获得逻辑声音,以便我能以正确的方式构建它。从逻辑上讲,LINQ似乎是最简单的模型,尽管我现在有了第二个想法。这是迄今为止我提出的用于获取年份和必要数据的代码。

var linqYears = from year in contextItem.Children
                select new
                {
                    Name = year.Fields["page title"],
                    URI = Sitecore.Links.LinkManager.GetItemUrl(year)
                };

我现在需要的是获得所选年份的所有月份,然后是所有文章,并将它们构建为转发器;我假设最简单的方法是通过DataTable / DataSet?

非常感谢任何帮助。

编辑:澄清我的立场:

item contextItem是我当前所在的页面。如果我在根页面上并且年份页面低于我,则contextItem.Children将返回其下的所有子项。例如,如果我在ROOT上,则给出此导航:

ROOT
- YEAR
- - MONTH
- - - ARTICLE 1
- - - ARTICLE 2

然后contextItem.Children将是一个仅由YEAR

组成的集合

1 个答案:

答案 0 :(得分:2)

我不熟悉您的结构,但我在此假设yearcontextItem的类型相同。如果是这样,这将有效:

var linqYears = from year in contextItem.Children
                select new
                {
                    Name = year.Fields["page title"],
                    URI = Sitecore.Links.LinkManager.GetItemUrl(year),
                    Months = from month in year.Children
                             select new
                             {
                                 Name = month.Fields["page title"],
                                 URI = Sitecore.Links.LinkManager.GetItemUrl(month),
                                 Articles = from article in month.Children
                                            select new
                                            {
                                                Name = article.Fields["page title"],
                                                URI = Sitecore.Links.LinkManager.GetItemUrl(article)
                                            }
                             }
                };

我不确定转发器,但您考虑过使用ListView吗?除非我被误解,否则你可以将它直接绑定到你的匿名类型。这只适用于你在线内选择这种选择。否则,我建议您创建一个包含Name,URI和Children的类,并将上述代码中的MonthsArticles分别替换为Children

希望有所帮助。

修改 要使此解决方案无论您在层次结构中的当前位置如何,都可以执行以下操作:

首先是您网页的课程。

public class PageNode
{
    public string Name { get; set; }
    public Uri URI { get; set; }
    public List<PageNode> Children { get; set; } // This should be done with a private setter, but you get that...
}

然后你需要类似的方法:

public IEnumerable<PageNode> GetChildNodes(IEnumerable<ContextItem> children)
{
    return from c in children
           select new PageNode()
           {
               Name = c.Fields["page name"],
               URI = Sitecore.Links.LinkManager.GetItemUrl(c),
               Children = c.Children.Any() ? GetChildNodes(c.Children) : null
           };
}

public PageNode LoadNode(ContextItem item)
{
    return new PageNode()
           {
               Name = item.Fields["page name"],
               URI = Sitecore.Links.LinkManager.GetItemUrl(item),
               Children = item.Children.Any() ? GetChildNodes(item.Children) : null
           };
}