简体   繁体   中英

ASP.NET repeater dynamic value

I try to use a repeater in repeater in ASP.NET, but I want to change datasource from every repeat.

My aspx markup is:

<div class="container px-4 py-5" id="custom-cards">
    <asp:Repeater ID="RepeaterKategori" runat="server" OnItemDataBound="ItemBound">
        <ItemTemplate>
            <h2 class="pb-2 border-bottom"><%#Eval("kategoriAd") %></h2>
            <div class="row row-cols-1 row-cols-md-3 g-4">
                <asp:Repeater ID="RepeaterAltKategori" runat="server">
                    <ItemTemplate>
                        <div class="col">
                            <div class="card h-100">
                                <img src="<%#Eval("altkategoriResim") %>" class="card-img-top" alt="...">
                                <div class="card-body">
                                    <h5 class="card-title"><%#Eval("altkategoriBaslik") %></h5>
                                    <p class="card-text"><%#Eval("altkategoriAciklama") %></p>
                                </div>
                                <div class="card-footer">
                                    <small class="text-muted">Teşekkürler : <%#Eval("altkategoriDestekci") %></small>
                                </div>
                            </div>
                        </div>
                    </ItemTemplate>
                </asp:Repeater>
            </div>
            <div class="d-grid gap-2 my-4">
                <a href="/yardim-kampanyalari.aspx" class="btn btn-outline-info" role="button">Tümünü Görüntüle</a>
            </div>
        </ItemTemplate>
    </asp:Repeater>
</div>

My aspx.cs code behind is:

rehber kod = new rehber();

protected void Page_Load(object sender, EventArgs e)
{
    RepeaterKategori.DataSource = kod.getDataTable("SELECT KategoriAd FROM kategoriler");
    RepeaterKategori.DataBind();
}

protected void ItemBound(object sender, RepeaterItemEventArgs args)
{
    if (args.Item.ItemType == ListItemType.Item || args.Item.ItemType == ListItemType.AlternatingItem)
    {
        DataTable katsay = kod.getDataTable("SELECT * FROM altkategoriler");
        int kategoris = katsay.Rows.Count;

        for (int i = 1; i == kategoris; i++)
        {
            Repeater RepeaterAltKategori = (Repeater)args.Item.FindControl("RepeaterAltKategori");
            RepeaterAltKategori.DataSource = kod.getDataTable("SELECT TOP 3 * FROM altkategoriler WHERE kategoriId="+i+"");
            RepeaterAltKategori.DataBind();
        }
    }
}

I want another id data like 1,2,3,4 for every repeat. How can I do this? Thanks..

You need to nest two repeaters then.

You have

top table - feed the main repeater - 1 record for each.

child table - feed the child repeater - child table - many records for each.

Also, make sure you ALWAYS use if (?isPostBack) to have a real first page load - if you don't do most (if not all) of your loading and databinding inside of the !IsPostback?

you cannot even really quite much build a working page that can survive post-backs.

Ok, so we have the master (top) repeater.

for the child repeater, you might have one record, maybe many. It don't matter. But WHAT DOES matter is you now have a whole new seperate data set and whole new set of Eval() and binding that belongs to that child table or child data set.

So, lets take a main repeater (our hotels), and for each instance, we drop in another repeater to display the child data (in this case people booked in the hotel).

So, we have this mark-up - note the nested 2nd repeater.

        <asp:Repeater ID="repHotels" runat="server" OnItemDataBound="repHotels_ItemDataBound">
            <ItemTemplate>
                <asp:Label ID="txtHotel" runat="server" Width="240px"
                    Text='<%# Eval("HotelName") %>' Font-Size="X-Large"                 > 
                </asp:Label>

                <asp:TextBox ID="txtDescription" runat="server"
                    Text='<%# Eval("Description") %>'
                    TextMode="MultiLine" Rows="5" Columns="40" Style="margin-left:20px" >
                </asp:TextBox>
                <br />
                <h4>People Booked</h4>
                <asp:Repeater ID="repPeopleBooked" runat="server">
                    <ItemTemplate>
                        <asp:Label ID="lFirst" runat="server" Text='<%# Eval("FirstName") %>'>
                        </asp:Label>
                        <asp:Label ID="lLast" runat="server" Text='<%# Eval("LastName") %>' 
                            style="margin-left:10px">
                        </asp:Label>
                        <br />
                    </ItemTemplate>
                </asp:Repeater>
                <%-- our repeat separator --%>
                <div style="height:20px">
                    <hr style="border:1px solid" />
                </div>
            </ItemTemplate>
        </asp:Repeater>

And our code to load. We ONLY load the main repeater data source, and THAT will trigger the item data bound event, and in that event then we deal with EACH separate instance of the child repeater.

Code like this:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
            LoadData();
    }


    void LoadData()
    {            
        SqlCommand cmdSQL = new SqlCommand("SELECT * from MyHotels ORDER BY HotelName");

        repHotels.DataSource = MyRstP(cmdSQL);
        repHotels.DataBind();
    }


    protected void repHotels_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        if ( (e.Item.ItemType == ListItemType.Item) || 
            (e.Item.ItemType == ListItemType.AlternatingItem))
        {
            // get child nested repeater
            Repeater rChild = e.Item.FindControl("repPeopleBooked") as Repeater;

            DataRowView rRow = ((DataRowView)e.Item.DataItem);
            string strSQL = "SELECT * FROM People WHERE Hotel_ID = @id";
            SqlCommand cmdSQL = new SqlCommand(strSQL);
            cmdSQL.Parameters.Add("@id", SqlDbType.Int).Value = rRow["ID"];

            rChild.DataSource = MyRstP(cmdSQL);
            rChild.DataBind();

        }
    }
    public DataTable MyRstP(SqlCommand cmdSQL)
    {
        DataTable rstData = new DataTable();
        using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
        {
            using (cmdSQL)
            {
                cmdSQL.Connection = conn;
                conn.Open();
                rstData.Load(cmdSQL.ExecuteReader());
            }
        }
        return rstData;
    }

and we now get this:

在此处输入图像描述

So, we see the 3 main records that drive the main repeater, and then we see the child records for the nested repeater.

Now, in your case, you might only ever have one child record - but it don't matter. What really matters is that you have the ability to deal with, and bind, and have separate Eval() and data for that child repeater.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM