<asp:Repeater ID="RepCourse" runat="server">
<ItemTemplate>
<div style="width:400px"></div>
<div class="course" style="float: left; margin-left: 100px; margin-top: 100px">
<div class="image">
<asp:Image ID="imgteacher" runat="server" Height="150" Width="248" ImageUrl='<%# "ShowImage.ashx?id="+ DataBinder.Eval(Container.DataItem, "CourseID") %>'/>
</div>
<div style="margin-left: 3px; width: 250px">
<div class="name">
<asp:Label runat="server" ID="lblname" Text='<%#Eval("CourseName") %>'></asp:Label>
</div>
<div style="height: 13px"></div>
<div id="teacher">
<%#Eval("UserName") %>
</div>
</div>
<div style="height: 4px"></div>
<div class="date">
<div id="datebegin">
<asp:Label ID="lbldatebegin" runat="server" Text='<%#Eval("BeginDate") %>'></asp:Label>
</div>
<div id="dateend">
<asp:Label ID="lbldateend" runat="server" Text='<%#Eval("ClosingDate") %>'></asp:Label>
</div>
</div>
</div>
</ItemTemplate>
</asp:Repeater>
In my project Repeater Control works fine. And now I need pagination for replacing those data. But I don't have any information about this. May be someone give me advice about this issue.
As shown below picture.
There's no built-in pagination in the Repeater control, but based on this article, you can achieve pagination in the Repeater control by creating another Repeater control for pages and use PagedDataSource as it's source.
First, add this to your markup:
<div style="overflow: hidden;">
<asp:Repeater ID="rptPaging" runat="server" OnItemCommand="rptPaging_ItemCommand">
<ItemTemplate>
<asp:LinkButton ID="btnPage"
style="padding:8px;margin:2px;background:#ffa100;border:solid 1px #666;font:8pt tahoma;"
CommandName="Page" CommandArgument="<%# Container.DataItem %>"
runat="server" ForeColor="White" Font-Bold="True">
<%# Container.DataItem %>
</asp:LinkButton>
</ItemTemplate>
</asp:Repeater>
</div>
Next, add the following property in your code behind:
//This property will contain the current page number
public int PageNumber
{
get
{
if (ViewState["PageNumber"] != null)
{
return Convert.ToInt32(ViewState["PageNumber"]);
}
else
{
return 0;
}
}
set { ViewState["PageNumber"] = value; }
}
Finally add the following methods:
protected void Page_Load(object sender, EventArgs e)
{
BindRepeater();
}
private void BindRepeater()
{
//Do your database connection stuff and get your data
SqlConnection cn = new SqlConnection(yourConnectionString);
SqlCommand cmd = new SqlCommand();
cmd.Connection = cn;
SqlDataAdapter ad = new SqlDataAdapter(cmd);
cmd.CommandText = "Select * from YourTable";
//save the result in data table
DataTable dt = new DataTable();
ad.SelectCommand = cmd;
ad.Fill(dt);
//Create the PagedDataSource that will be used in paging
PagedDataSource pgitems = new PagedDataSource();
pgitems.DataSource = dt.DefaultView;
pgitems.AllowPaging = true;
//Control page size from here
pgitems.PageSize = 4;
pgitems.CurrentPageIndex = PageNumber;
if (pgitems.PageCount > 1)
{
rptPaging.Visible = true;
ArrayList pages = new ArrayList();
for (int i = 0; i <= pgitems.PageCount - 1; i++)
{
pages.Add((i + 1).ToString());
}
rptPaging.DataSource = pages;
rptPaging.DataBind();
}
else
{
rptPaging.Visible = false;
}
//Finally, set the datasource of the repeater
RepCourse.DataSource = pgitems;
RepCourse.DataBind();
}
//This method will fire when clicking on the page no link from the pager repeater
protected void rptPaging_ItemCommand(object source, System.Web.UI.WebControls.RepeaterCommandEventArgs e)
{
PageNumber = Convert.ToInt32(e.CommandArgument) - 1;
BindRepeater();
}
Please give it a try and if you faced any issue just inform me.
Edit: Alternative Solution
Another excellent solution can be found Here, this solution includes the Navigation buttons of pages. You'll need to download files from that link to see a functional pagination and just replace the DataList control with your Repeater control.
Hope this helps.
Related
I have 2 dropdownlist on my web form and the second one is synchronised with the first one based upon what value has been chosen.
Everything works well between the 2 of them and am able to use the values from them to carry out my function.
However the first dropdownlist seems to have an effect on my repeater and paginations. Basically it keeps incrementing the pageddatesource and clears the repeater of any data ?
The SelectedIndexChanged is only meant to update the update.panel1 where the second dropdownlist is but then am not sure how it further increments the page numbers and removes data from repeater?
Here is the front end with the dropdownlists.
<section id="section-search">
<div class="fleft">
Start Date:
<asp:TextBox runat="server" ID="txtStartDate" CssClass="txt txt-sml"></asp:TextBox>
<ajaxToolkit:CalendarExtender ID="calStartDate" runat="server" PopupPosition="Right" Animated="true" TargetControlID="txtStartDate" />
End Date:
<asp:TextBox runat="server" ID="txtEndDate" CssClass="txt txt-sml"></asp:TextBox>
<ajaxToolkit:CalendarExtender runat="server" ID="calEndDate" PopupPosition="Right" Animated="true" TargetControlID="txtEndDate"></ajaxToolkit:CalendarExtender>
<hr />
Product Class:
<asp:DropDownList ID="drpProductClass" runat="server" Width="230px" OnSelectedIndexChanged="drpProductClass_SelectedIndexChanged" AutoPostBack="true" />
<hr />
<asp:UpdatePanel ID="updatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
Product:
<asp:DropDownList ID="drpProduct" runat="server" Width="230px" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
<div class="fright">
<asp:Button runat="server" ID="btnFilter" Text="Search" CssClass="submit" OnClick="btnFilter_Click"/>
</div>
</section>
<section id="section-title">
<h1>Order Search</h1><h2></h2>
</section>
<section class="info-strip tr">
<asp:Literal ID="litResults" runat="server"></asp:Literal>
</section>
<section class="track-table">
<asp:Literal runat="server" ID="litMessage" Visible="false" Text="<div class='wysiwyg'><p>You currently have no orders...</p></div>"></asp:Literal>
<asp:PlaceHolder runat="server" ID="phOrders">
<%--<table>
<thead>
</thead>
<tbody>--%>
<asp:Repeater ID="rprOrders" runat="server" OnItemCommand="rprOrders_ItemCommand" >
Here is my Code behind
protected void SetupControl()
{
if (this.StopProcessing)
{
// Do not process
}
else
{
if (CMSContext.ViewMode == ViewModeEnum.LiveSite)
{
if(!Page.IsPostBack)
{
PopulateProductClass();
PopulateProduct();
PopulateOrders();
}
}
}
}
protected void drpProductClass_SelectedIndexChanged(object sender, EventArgs e)
{
CustomTableItemProvider ctip = new CustomTableItemProvider();
UserInfo user = CooneenHelper.GetUserImpersonisationUser();
QueryDataParameters qdp = new QueryDataParameters();
qdp.Add("#UserID", user.UserID);
DataSet ds = gc.ExecuteQuery("CN_GetEmpIDByUID", qdp, QueryTypeEnum.StoredProcedure, true);
int emplID = Convert.ToInt32(ds.Tables[0].Rows[0]["UserEmployeeID"].ToString());
if (drpProductClass.SelectedValue.ToString() != "0")
{
QueryDataParameters qdp2 = new QueryDataParameters();
qdp2.Add("#WR_ClassID", Convert.ToInt32(drpProductClass.SelectedValue.ToString()));
qdp2.Add("#UserEmployeeID", emplID);
DataSet ds2 = gc.ExecuteQuery("CN_OrdersGetProductByClassID", qdp2, QueryTypeEnum.StoredProcedure, true);
drpProduct.ClearSelection();
drpProduct.DataSource = ds2.Tables[1];
drpProduct.DataTextField = "ProductName";
drpProduct.DataValueField = "SKUNumber";
drpProduct.DataBind();
drpProduct.Items.Insert(0, new ListItem("-- Select Product --", "0"));
updatePanel1.Update();
}
else
{
drpProduct.ClearSelection();
PopulateProduct();
}
}
private void PopulateOrders()
{
CustomerInfo ki = CustomerInfoProvider.GetCustomerInfoByUserID(CooneenHelper.GetUserImpersonisationID());
int nKustomerID = ki.CustomerID;
DataTable dts = new DataTable();
dts.Columns.Add("OrderDate", typeof(string));
dts.Columns.Add("OrderNumber", typeof(string));
dts.Columns.Add("OrderItemSKUName", typeof(string));
dts.Columns.Add("OrderItemSKUID", typeof(string));
dts.Columns.Add("OrderItemStatus", typeof(string));
dts.Columns.Add("OrderItemUnitCount", typeof(string));
QueryDataParameters qdp = new QueryDataParameters();
qdp.Add("#CustomerID", nKustomerID);
DataSet ds = gc.ExecuteQuery("CN_OrderList", qdp, QueryTypeEnum.StoredProcedure, true);
foreach (DataRow dr in ds.Tables[0].Rows)
{
DataRow drNew = dts.NewRow();
drNew["OrderDate"] = ValidationHelper.GetDateTime(dr["OrderDate"], DateTime.Now).ToShortDateString();
drNew["OrderNumber"] = dr["OrderNumber"].ToString();
drNew["OrderItemSKUName"] = dr["OrderItemSKUName"].ToString();
drNew["OrderItemSKUID"] = dr["OrderItemSKUID"].ToString();
drNew["OrderItemStatus"] = dr["OrderItemStatus"].ToString();
drNew["OrderItemUnitCount"] = dr["OrderItemUnitCount"].ToString();
dts.Rows.Add(drNew);
}
PagedDataSource pds = new PagedDataSource();
pds.DataSource = dts.DefaultView;
//DataView view = dts.DefaultView;
//allow paging, set page size, and current page
pds.AllowPaging = true;
pds.PageSize = PerPage;
pds.CurrentPageIndex = CurrentPage;
//show # of current page in label
if (pds.PageCount > 1) litResults.Text += " - Showing page " + (CurrentPage + 1).ToString() + " of " + pds.PageCount.ToString();
//disable prev/next buttons on the first/last pages
btnPrev.Enabled = !pds.IsFirstPage;
btnNext.Enabled = !pds.IsLastPage;
rprOrders.Visible = true;
rprOrders.DataSource = pds;
rprOrders.DataBind();
}
We had a similar problem and could never figure out the root cause of it, we chalked it up to a bug in WebForms. But we were able to get around the problem by setting ClientIDMode="AutoID" for the control or page, we ended up setting our entire site that way cause we found problems that it happened to solve. Let me know if this works for you too. Wish I could be of greater help.
How to populate a repeater with two separate list
I have the following repeater:
<div style="width: 100%; overflow: hidden;">
<asp:Repeater ID="rptLabels" runat="server" ClientIDMode="Static">
<HeaderTemplate>
<div class="hidOverflow setFloatL smallPadLeft" style="width: 45%; float: left;">
</HeaderTemplate>
<ItemTemplate>
<div class="hidOverflow smallPad">
<div class="setFloatL halfWidth vertAlignT">
<asp:Label ID="lbl1" ClientIDMode="Static" runat="server" Text="<%# Container.DataItem.ToString() %>"></asp:Label>
</div>
<div class="setFloatL vertAlignT">
<asp:Label ID="lbl2" ClientIDMode="Static" runat="server" Text="<%# Container.DataItem.ToString() %>"></asp:Label>
</div>
</div>
</ItemTemplate>
<FooterTemplate>
</div>
</FooterTemplate>
</asp:Repeater>
<asp:Repeater ID="rptLabels2" runat="server" ClientIDMode="Static">
<HeaderTemplate>
<div class="hidOverflow setFloatL smallPadLeft" style="width: 45%; float: left;">
</HeaderTemplate>
<ItemTemplate>
<div class="hidOverflow smallPad">
<div class="setFloatL halfWidth vertAlignT">
<asp:Label ID="lbl3" ClientIDMode="Static" runat="server" Text="<%# Container.DataItem.ToString() %>"></asp:Label>
</div>
<div class="setFloatL vertAlignT">
<asp:Label ID="lbl4" ClientIDMode="Static" runat="server" Text="<%# Container.DataItem.ToString() %>"></asp:Label>
</div>
</div>
</ItemTemplate>
<FooterTemplate>
</div>
</FooterTemplate>
</asp:Repeater>
</div>
I am trying to populate the column name into each lbl1 and the row value of the corresponding column into each lbl2. I have the following code:
List<string> colO = new List<string>();
List<string> colOV = new List<string>();
List<string> colT = new List<string>();
List<string> colTV = new List<string>();
using (SqlConnection conn = new SqlConnection(gloString))
{
string strQuery = #""; //query which generates the dataset
try
{
SqlDataAdapter da = new SqlDataAdapter(strQuery, conn);
DataSet myDataSet = new DataSet();
da.Fill(myDataSet);
DataTable myDataTable = new DataTable();
myDataTable = myDataSet.Tables[0];
for (i = 0; i < myDataSet.Tables[0].Columns.Count / 2; i++)
{
lop += myDataSet.Tables[0].Columns[i].ColumnName + " ";
colO.Add(myDataSet.Tables[0].Columns[i].ColumnName.ToString()); //column name
colOV.Add(myDataSet.Tables[0].Rows[0][i].ToString()); //row value of the column
}
lop += "\n\n";
for (int j = i; j < myDataSet.Tables[0].Columns.Count; j++)
{
lop += myDataSet.Tables[0].Columns[j].ColumnName + " ";
colT.Add(myDataSet.Tables[0].Columns[j].ColumnName.ToString()); //column name
colTV.Add(myDataSet.Tables[0].Rows[0][j].ToString()); //row value of the column
}
rptLabels.DataSource = colO; //I would like to popupate "colO" into "lbl1" and "colOV" into "lbl2" inside "rptLabels" repeater
rptLabels.DataBind();
rptLabels2.DataSource = colT; //I would like to popupate "colT" into "lbl3" and "colTV" into "lbl4" inside "rptLabels2" repeater
rptLabels2.DataBind();
}
catch (SqlException)
{
}
}
Right now I can only use one list for the datasource for each repeater. How can I modify the code to achieve the following:
rptLabels.DataSource = colO; //I would like to popupate "colO" into "lbl1" and "colOV" into "lbl2" inside "rptLabels" repeater
rptLabels.DataBind();
rptLabels2.DataSource = colT; //I would like to popupate "colT" into "lbl3" and "colTV" into "lbl4" inside "rptLabels2" repeater
rptLabels2.DataBind();
Your DataTable could to be accessed in the form of array of muti-dimension, besides being the most briefly to access rows and columns. For example:
myDt.Rows[0][0]; // access the first row and first column
myDt.Rows[0][1]; // access the first row and second column
myDt.Rows[0][2]; // access the first row and third column
myDt.Rows[1][0]; // access the second row and first column
myDt.Rows[1][1]; // access the second row and second column
myDt.Rows[1][2]; // access the second row and third column
If you need can go all fields returned using two nested for statement:
for(int i = 0;i < dtData.Rows.Count;i++)//travels the rows
{
for(int j = 0;j < dtData.Rows.Count;j++)//travels the columns
{
var valueField = myDt.Rows[i][j];//access the value of current field
}
}
Each row contains individual columns. You can access it through
Rows[i].ItemArray
I am trying to use the Telerik RadListView Drag-Drop feature:
http://demos.telerik.com/aspnet-ajax/listview/examples/datagrouping/defaultcs.aspx
The code below works fine but loops through all the items to find the "e.DestinationHtmlElement" which is not efficient. I want to be able to drag an item from one data group to another data group for Telerik RadListView with a better algorithm. How can I do that?
ASPX Code:
<telerik:RadListView runat="server" ID="Lsv_Vis" AllowPaging="True" PageSize="50"
ItemPlaceholderID="Phi_Vis_I" GroupPlaceholderID="Phi_Vis_G"
DataKeyNames="url_id, lst_id, url_name, url_address"
ClientDataKeyNames="url_id, lst_id, url_name, url_address"
OnItemDrop="CsVisItemDrop" OnItemDataBound="CsVisIDB" DataSourceID="Sql_Vis">
</telerik:RadListView>
<DataGroups>
<telerik:ListViewDataGroup GroupField="lst_id" DataGroupPlaceholderID="Phi_Vis_G">
<DataGroupTemplate>
<div class="Div_Vis_Grp"><span class="Spn_Vis"><%# (Container as RadListViewDataGroupItem).AggregatesValues["lst_name"].ToString() %></span></div>
<asp:Panel ID="Pnl_Vis" runat="server" CssClass="Pnl_Vis" ToolTip='<%# (Container as RadListViewDataGroupItem).DataGroupKey %>' onmouseover='this.className += " Vis_Sel";' onmouseout='this.className = this.className.split(" Vis_Sel").join("");'>
<asp:PlaceHolder ID="Phi_Vis_I" runat="server" />
</asp:Panel>
</DataGroupTemplate>
<GroupAggregates>
<telerik:ListViewDataGroupAggregate Aggregate="Max" DataField="lst_name" />
</GroupAggregates>
</telerik:ListViewDataGroup>
</DataGroups>
<ItemTemplate>
<div class="Div_Vis_Item rlvI">
<asp:Panel ID="Pnl_Vis" runat="server" ToolTip='<%# Eval("lst_id") %>' CssClass="Div_Vis_Item" onmouseover='this.className += " Vis_Sel";' onmouseout='this.className = this.className.split(" Vis_Sel").join("");'>
<a class="Hyp_Vis" runat="server" href='<%# Eval("url_address") %>' target="_blank">
<div class="Div_Vis_Body">
<div class="Div_Vis_Con">
<asp:Panel ID="Div_Vis_Con" runat="server" class="Div_Vis_Con" ToolTip='<%# Eval("lst_id") %>' ></asp:Panel>
</div>
</div>
<div class="Div_Vis_Link">
<asp:Label ID="Lbl_VisI" runat="server" Text='<%# Eval("url_name_short") %>' ToolTip='<%# Eval("url_name") %>'/>
</div>
</a>
</asp:Panel>
</div>
</ItemTemplate>
C# Code:
protected void CsVisItemDrop (object sender, RadListViewItemDragDropEventArgs e)
{
if (e.DestinationHtmlElement.IndexOf("Div_Vis_Con") < 0)
{
return;
}
foreach (RadListViewDataItem di in Lsv_Vis.Items)
{
Panel pnl = di.FindControl("Div_Vis_Con") as Panel;
if (pnl != null && pnl.ClientID == e.DestinationHtmlElement)
{
string uid = e.DraggedItem.GetDataKeyValue("url_id").ToString();
string lid = pnl.ToolTip.ToString();
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["Con_Str"].ToString()))
{
using (SqlCommand cmd = new SqlCommand("UPDATE [MyTable] SET lst_id = #lst_id WHERE url_id = #url_id", conn))
{
cmd.Parameters.Add("#lst_id", SqlDbType.VarChar).Value = lid;
cmd.Parameters.Add("#url_id", SqlDbType.VarChar).Value = uid;
try
{
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
catch { }
}
}
}
}
Lsv_Vis.Rebind();
}
I have an accordion that has another accordion inside one of its panes. This inner accordion is created using a datasource so each of its panes are loaded from a list of objects. In this particular case, this datasource is also loaded on demand. Now, where I'm stuck is that I want to be able to load the pane headers only and then load the contents when the pane is clicked; similar to what I have in the outer pane. The reason I'm confused here, is because the lazy load happens when the pane is clicked, but since this happens AFTER the databind, I don't know how to reference the content of the pane that invokes the ItemCommand. Not sure if that makes sense. Here is the inner accordion:
<ajaxToolkit:Accordion runat="server" ID="accReviewers" OnItemDataBound="accOuterAccordion_ItemDataBound" ContentCssClass="ReviewerContent" RequireOpenedPane="False" SelectedIndex="-1" OnItemCommand="accReviewers_ItemCommand">
<HeaderTemplate>
<div>
<asp:LinkButton Text='<%#Eval("Header") %>' CssClass="InReviewHeader" runat="server"
CommandName="LoadReviewers" CommandArgument='<%#Eval("MocRequestId") %>'/>
</div>
</HeaderTemplate>
<ContentTemplate>
<div>
<asp:ListView runat="server" ID="lvReviewers" ItemPlaceholderID="phReviewer" OnItemDataBound="lvReviewers_ItemDataBound">
<LayoutTemplate>
<div>
<asp:HyperLink runat="server" ID="lnkGotoRequest" Text="View this request"/>
</div>
<asp:PlaceHolder runat="server" ID="phReviewer"/>
<div style="margin-top: 5px;">
<asp:Button runat="server" ID="btnResubmit" Text="Resubmit" CssClass="ResubmitInitial"/>
</div>
</LayoutTemplate>
<ItemTemplate>
<div class="ReviewerItem">
<%#Eval("Assignee.Name") %><br />
<img src="" alt="Reviewer" runat="server" ID="imgReviewer" width="75" style="border: 1px solid gray; border-radius: 6px;"/><br />
<asp:Label runat="server" ID="lblStatus" Text='<%#Eval("ReviewStatus") %>' />
<asp:HyperLink runat="server" ID="lnkRejectComment" CssClass="InitialRejectComment">(details)</asp:HyperLink>
</div>
</ItemTemplate>
</asp:ListView>
</div>
</ContentTemplate>
</ajaxToolkit:Accordion>
</Content>
</ajaxToolkit:AccordionPane>
As you can see, the accordion accReviewers is generated via a DataSource. The listview contained in the LayoutTemplate will not have its datasource bound until the LinkButton has been clicked, which will fire the item command. Also worth noting that this entire accordion is wrapped in an UpdatePanel.
This is the code behind I was starting to work with, but it doesn't appear to get the correct instance of the listview and while the list is not empty, it will not display anything:
protected void accReviewers_ItemCommand(object sender, CommandEventArgs e)
{
var mocId = int.Parse(e.CommandArgument.ToString());
var list = (sender as AjaxControlToolkit.Accordion).FindControl("lvReviewers") as ListView; //APPARENTLY WRONG
var reviewers = MocApi.GetReviews(mocId);
list.DataSource = reviewers;
list.DataBind();
}
So to recap, when the LinkButton within the HeaderTemplate is clicked, I need to somehow gain reference to the correct instance of the ListView so that I can bind its datasource. As always, any help or insight is appreciated. This is similar to a previous question of mine but is specific to gaining this reference after databind which seems a bit more complicated. TIA
UPDATE:
I found that I can bind the item datasource if I can somehow capture its index. I'm exploring trying to set that as a command argument during the databinding of the inner accordion.
I managed to solve this with some minor shenannigans:
Here is the markup:
<ItemTemplate>
<div class="ReviewerItem">
<%#Eval("Assignee.Name") %><br />
<div style="display: inline-block; position: relative;">
<img src="" alt="Reviewer" runat="server" ID="imgReviewer" width="75" style="border: 1px solid lightgray; border-radius: 6px; overflow: hidden;"/><br />
<div runat="server" ID="divYes" Visible="False">
<img src="../Images/Yes.png" alt="Approved" class="ApprovalIcon" />
</div>
<div runat="server" ID="divNo" Visible="False">
<img src="../Images/No.png" alt="Rejected" class="ApprovalIcon" id="imgNo" />
</div>
</div>
<asp:Label runat="server" ID="lblStatus" Text='<%#Eval("ReviewStatus") %>' />
<asp:HyperLink runat="server" ID="lnkRejectComment" CssClass="InitialRejectComment">(details)</asp:HyperLink>
<asp:Panel runat="server" ID="pnlDemoApproval" Visible="False" CssClass="DemoButtons">
<asp:Button runat="server" ID="btnApprove" Text="Approve" CommandArgument='<%#Eval("Assignee.Guid") + "|" + Eval("Ticketid") %>' CommandName="ApproveReview"/>
<asp:Button runat="server" ID="btnDeny" Text="Deny" CommandArgument='<%#Eval("Assignee.Guid") + "|" + Eval("Ticketid") %>' CommandName="DenyReview"/>
</asp:Panel>
<ajaxToolkit:BalloonPopupExtender runat="server" ID="balloon" BalloonPopupControlID="pnlPopup"
TargetControlID="lnkRejectComment" Position="TopRight" BalloonStyle="Cloud" BalloonSize="Medium" DisplayOnMouseOver="True"/>
<asp:Panel runat="server" ID="pnlPopup">Rejection Reason</asp:Panel>
</div>
</ItemTemplate>
On databind, I catch the item so that I can grab the index and set it to the CommandName for later use:
AjaxControlToolkit.AccordionItemEventArgs e)
{
if (e.ItemType != AjaxControlToolkit.AccordionItemType.Content) return;
var index = e.ItemIndex;
var button = e.AccordionItem.Parent.FindControl("lnkbHeader") as LinkButton;
if (button != null) button.CommandName = index.ToString();
}
Now that control contains the index, i can use that to target the correct pane and bind its datasource:
protected void accReviewers_ItemCommand(object sender, CommandEventArgs e)
{
//This seems stupid to put here, but for some reason the item command bypasses the listview catch and passes it to the accordion
if (e.CommandName == "ApproveReview")
{
var assigneeGuid = new Guid(e.CommandArgument.ToString().Split('|')[0]);
var ticketId = int.Parse(e.CommandArgument.ToString().Split('|')[1]);
var ticket = new MocApproval(ticketId);
DoDemoApproval(ticketId, assigneeGuid, true);
var approvalIndex = (sender as AjaxControlToolkit.Accordion).SelectedIndex;
var lv =
(sender as AjaxControlToolkit.Accordion).Panes[approvalIndex].FindControl("lvReviewers") as ListView;
lv.DataSource = MocApi.GetReviews(ticket.MocRequest);
lv.DataBind();
return;
}
if (e.CommandName == "DenyReview")
{
var assigneeGuid = new Guid(e.CommandArgument.ToString().Split('|')[0]);
var ticketId = int.Parse(e.CommandArgument.ToString().Split('|')[1]);
var ticket = new MocApproval(ticketId);
DoDemoApproval(ticketId, assigneeGuid, false);
var approvalIndex = (sender as AjaxControlToolkit.Accordion).SelectedIndex;
var lv =
(sender as AjaxControlToolkit.Accordion).Panes[approvalIndex].FindControl("lvReviewers") as ListView;
lv.DataSource = MocApi.GetReviews(ticket.MocRequest);
lv.DataBind();
return;
}
...
I have a set of items coming from the database. Their number may vary. I have bound them in a repeater. Now my following example will explain what I want:
I have 11 items coming from database, I want them to be grouped in terms of 5 items per row.
1st row: 5 items.
2nd row: 5 items.
3rd row: 1 item.
Currently, I am just binding them in a repeater. How do I do this?
Yes. It is possible:
<asp:Repeater ID="rptItems" runat="server">
<ItemTemplate>
<asp:Literal runat="server" Text='<%# Eval("Value") %>'></asp:Literal>
<div style="clear: both" runat="server" Visible="<%# (Container.ItemIndex+1) % 5 == 0 %>"></div>
</ItemTemplate>
</asp:Repeater>
It produces following results for the sequence of numbers:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
if you can use ListView, then you can use GroupItemCount . some thing like this MSDN Example
<asp:ListView ID="ContactsListView"
DataSourceID="yourDatasource"
GroupItemCount="5"
runat="server">
<LayoutTemplate>
<table id="tblContacts" runat="server" cellspacing="0" cellpadding="2">
<tr runat="server" id="groupPlaceholder" />
</table>
</LayoutTemplate>
<ItemTemplate>
<div> your Items here </div>
</ItemTemplate>
<GroupTemplate>
<tr runat="server" id="ContactsRow" style="background-color: #FFFFFF">
<td runat="server" id="itemPlaceholder" />
</tr>
</GroupTemplate>
<ItemSeparatorTemplate>
<td runat="server" style="border-right: 1px solid #00C0C0"> </td>
</ItemSeparatorTemplate>
</asp:ListView>
If you want to stick with a Repeater, I can think of two approaches.
Firstly, you could stick with a flat list of items and make the repeater insert a "new line" after each 5th item. You should be able to do this in the <ItemTemplate> with a block like
<% if ((Container.DataItemIndex % 5) == 4) { %>
</div>
<div>
<% } %>
which honestly isn't very nice.
Alternatively, you could use MoreLINQ's Batch method to batch your items up into IEnumerables of 5, and then use two nested repeaters to render them. Set the outer repeater to wrap the inner repeater in <div> tags, and set the inner repeater's DataSource='<%# Container.DataItem %>'. This should result in much cleaner markup.
You can try below, I mistakenly said ListView, actually I meant DataList
<asp:DataList ID="DataList1" runat="server" RepeatColumns="5"
RepeatDirection="Horizontal" RepeatLayout="Flow">
<ItemTemplate >
<%--Your Item Data goes here--%>
</ItemTemplate>
</asp:DataList>
You may use nested Data controls (i.e Repeater) and also handle the OnItemDataBound event to bind the inner Repeater.
Sample Data Source component:
public class Item
{
public int ID { get; set; }
public string Name { get; set; }
public static List<List<Item>> getItems()
{
List<Item> list = new List<Item>()
{
new Item(){ ID=11, Name="A"},
new Item(){ ID=12, Name="B"},
new Item(){ ID=13, Name="C"},
new Item(){ ID=14, Name="D"},
new Item(){ ID=15, Name="E"},
};
/* Split the list as per specified size */
int size = 2;
var lists = Enumerable.Range(0, (list.Count + size - 1) / size)
.Select(index => list.GetRange(index * size,
Math.Min(size, list.Count - index * size)))
.ToList();
return lists;
}
}
Markup (.aspx)
<asp:Repeater ID="outerRepeater"
runat="server" onitemdatabound="outerRepeater_ItemDataBound"
>
<ItemTemplate>
<p>
Row
</p>
<asp:Repeater ID="innerRepeater"
runat="server">
<ItemTemplate>
<asp:Literal ID="literal1" runat="server" Text='<%# Eval("ID") %>' />
<asp:Literal ID="literal2" runat="server" Text='<%# Eval("Name") %>' />
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
Code-behind
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
outerRepeater.DataSource = Item.getItems();
outerRepeater.DataBind();
}
}
protected void outerRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
Repeater repeater = e.Item.FindControl("innerRepeater") as Repeater;
repeater.DataSource = Item.getItems()[e.Item.ItemIndex];
repeater.DataBind();
}
<asp:Repeater ID="Repeater1" runat="server"
OnItemDataBound="Repeater1_databinding">
<HeaderTemplate>
<table id="masterDataTable" class="reportTable list issues" width="100%">
<thead>
<tr>
<asp:Literal ID="literalHeader" runat="server"></asp:Literal>
</tr>
</thead>
<tbody>
</HeaderTemplate>
<ItemTemplate>
<tr>
<asp:Literal ID="literals" runat="server"></asp:Literal>
</tr>
</ItemTemplate>
<FooterTemplate>
</tbody> </table>
</FooterTemplate>
</asp:Repeater>
<input id="hdnColumnName" runat="server" clientidmode="Static" type="hidden" />
<input id="hdnColumnOrder" runat="server" clientidmode="Static" type="hidden" />
// javascript Function
<script type="text/javascript">
$(document).ready(function () {
$('#ddlReport').removeClass('required');
$('.sort').click(function () {
$('#hdnColumnName').val($(this).text());
$('#hdnColumnOrder').val($(this).attr('class'));
$(this).toggleClass("desc asc");
$("#lnkSort").click();
});
});
</script>
// Bind repeater
DataTable dt = objReport.GetCustomRecord();
fn = new List<string>();
for (int i = 0; i < dt.Columns.Count; i++)
{
if (dt.Columns[i].ColumnName != "Maxcount" )
{
fn.Add(dt.Columns[i].ColumnName);
}
}
Repeater1.DataSource = dt;
Repeater1.DataBind();
protected void Repeater1_databinding(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Header)
{
if (e.Item.FindControl("literalHeader") != null)
{
StringBuilder sb = new StringBuilder();
Literal li = e.Item.FindControl("literalHeader") as Literal;
fieldName().ForEach(delegate(string fn)
{
if (hdnColumnName.Value != fn.ToString())
{
sb.Append("<th width=\"10%\"> <a id=\"btnCustomerName\" class=\"sort desc\" onclick=\"btnSorts_onclick()\" style=\"cursor:pointer;text-decoration: none !important;\" >"
+ fn.ToString() + "</a></th>");
}
else
{
if (hdnColumnOrder.Value == "sort asc")
sb.Append("<th width=\"10%\"> <a id=\"btnCustomerName\" class=\"sort desc\" onclick=\"btnSorts_onclick()\" style=\"cursor:pointer;text-decoration: none !important;\" >"
+ fn.ToString() + "</a></th>");
else
sb.Append("<th width=\"10%\"> <a id=\"btnCustomerName\" class=\"sort asc\" onclick=\"btnSorts_onclick()\" style=\"cursor:pointer;text-decoration: none !important;\">"
+ fn.ToString() + "</a></th>");
}
});
li.Text = sb.ToString();
}
}
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
if (e.Item.FindControl("literals") != null)
{
DataRowView drv = (DataRowView)e.Item.DataItem;
Literal li = e.Item.FindControl("literals") as Literal;
StringBuilder sb = new StringBuilder();
fieldName().ForEach(delegate(string fn)
{
sb.Append("<td>" + drv[fn.ToString()] + "</td>");
});
li.Text = sb.ToString();
}
}
}