分层Nester Repeater重复父项

时间:2012-06-26 00:53:11

标签: asp.net database ms-access datatable repeater

我正在尝试使用来自Access数据源的嵌套转发器生成分层列表。 每个项目都有一个唯一的ID,但根据区域进行分类。

我希望列表看起来像:

  • 区域1
    • ITEM1
    • ITEM2
  • 区域2
    • 项目3
    • ITEM4
  • ...

尽我所能,区域组元素不断重复,我得到类似的东西:

  • 区域1
    • ITEM1
  • 区域1
    • ITEM2
  • 区域2
    • 项目3
  • 区域2
    • ITEM4
  • ...

我的标记发布在下面。

      <asp:Repeater ID="CategoryRepeater" runat="server" OnItemDataBound="CategoryRepeater_bound" EnableViewState="false">
            <HeaderTemplate>
                <ul>
            </HeaderTemplate>
            <FooterTemplate>
                </ul>
            </FooterTemplate>
            <ItemTemplate>
                <li>
                    <%#((DataRowView)Container.DataItem)["Area"]%>
                </li>
                    <asp:Repeater ID="childRepeater" runat="server">
                        <HeaderTemplate>
                            <ul>
                        </HeaderTemplate>
                        <FooterTemplate>
                            </ul>
                        </FooterTemplate>
                        <ItemTemplate>
                            <li>
                                <%#((DataRowView)Container.DataItem)["ItemID"]%>
                            </li>                     
                        </ItemTemplate>
                    </asp:Repeater>
            </ItemTemplate>
        </asp:Repeater>




protected void Page_Load(object sender, EventArgs e)
{
    string cn = "Provider=Microsoft.Jet.OleDb.4.0;Data Source=|DataDirectory|Source.mdb";

using (OleDbConnection conn = new OleDbConnection(cn))
  {

    OleDbCommand cmd = new OleDbCommand("Select ItemID, Area FROM [Location]", conn);
    OleDbDataAdapter da = new OleDbDataAdapter(cmd);


    DataSet ds = new DataSet();
    da.Fill(ds, "Table1");
    cmd.CommandText = "SELECT Area, ItemID, Drawing FROM [Location]";
    da.SelectCommand = cmd;
    da.Fill(ds, "Table2");
    ds.Relations.Add(new DataRelation("drTable", ds.Tables["Table1"].Columns["ItemID"], ds.Tables["Table2"].Columns["ItemID"]));
    CategoryRepeater.DataSource = ds.Tables["Table1"];
    CategoryRepeater.DataBind();
  }
}



protected void CategoryRepeater_bound(object source, RepeaterItemEventArgs e)
{
    RepeaterItem item = e.Item;
    if (item.ItemType == ListItemType.AlternatingItem || item.ItemType == ListItemType.Item)
    {
        DataRowView drv = (DataRowView)e.Item.DataItem;

        Repeater rep = (Repeater)item.FindControl("childRepeater");
        rep.DataSource = drv.CreateChildView("drTable");
        rep.DataBind(); 

     }

}

2 个答案:

答案 0 :(得分:2)

您需要将子转发器放在<li></li>标记内,此时它位于其外部,从而导致主要的html布局问题。你的整个逻辑也是错误的。在您的第一个查询中,您选择的是Select ItemID, Area FROM [Location]这样的区域,这将返回如下数据:

Area 1  Item 1
Area 1  Item 2
Area 2  Item 3
Area 2  Item 4

等等,所以转发器会相应地分组。因此,当您将父项绑定到这些结果时,您将获得Area1,Area1,Area2,Area2 ......我将避免使用数据表,并且可能使用类似Linq to SQL或Entity Framework的内容。但在你的情况下,最快的修复方法如下:

添加标签

<li>                           
    <asp:Label ID="lblArea" runat="server" Text='<%#((DataRowView)Container.DataItem)["Area"]%>' />                       
</li>

代码

protected void Page_Load(object sender, EventArgs e)    {        
    string cn = "Provider=Microsoft.Jet.OleDb.4.0;Data Source=|DataDirectory|Source.mdb";        
    using (OleDbConnection conn = new OleDbConnection(cn))      
    {            
        OleDbCommand cmd = new OleDbCommand("Select Area FROM [Location]", conn);        
        OleDbDataAdapter da = new OleDbDataAdapter(cmd);                
        DataSet ds = new DataSet();        
        da.Fill(ds, "Table1");               
        CategoryRepeater.DataSource = ds.Tables["Table1"];                    
        categoryRepeater.DataBind();      
    }    
}

protected void CategoryRepeater_bound(object source, RepeaterItemEventArgs e) 
{             
    RepeaterItem item = e.Item;             
    if (item.ItemType == ListItemType.AlternatingItem || item.ItemType == ListItemType.Item)             
    {                             
        Repeater rep = (Repeater)item.FindControl("childRepeater");  
        Label lblArea = (Label)item.FindControl("lblArea");  

        OleDbCommand cmd = new OleDbCommand("Select ItemID, Drawind FROM [Location] WHERE Area = '" + lblArea.Text+ "'", conn);        
        OleDbDataAdapter da = new OleDbDataAdapter(cmd);                
        DataSet ds = new DataSet();        
        da.Fill(ds, "Table1");               
        rep.DataSource = ds.Tables["Table1"];                    
        rep.DataBind();  
    }                  
}

答案 1 :(得分:1)

我认为你错误地设置了DataRelation。根据您的代码,您将Area作为父项,将ItemId作为子项。但是,在创建DataRelation时,可以将两个表中的列设置为ItemId。这将导致子表与父表一对一。

您应该在列Area上设置DataRelation。这应该解决我相信的问题。

但是如果父表包含多个具有相同Area的行,那么这将不起作用,因此您可能必须更改用于填充父表的SQL(Table1)。目前还不清楚是否有必要,但我认为这样做。也许是这样的:

OleDbCommand cmd = new OleDbCommand("Select DISTINCT Area FROM [Location]", conn); 

希望这有帮助。

编辑:另请参阅fenix2222关于格式错误的HTML的答案。