Paging not Working Correctly in asp Repeater - c#

I am binding an ASP Repeater from List & trying to add paging in the repeater. Each Page would have 5 Rows. when The Page is Run, 5 items are visible fine but when I click on "2" link button, nothing is visible. When I again Click on "1" the items of Page 2 are visible.
I've gone through this to implement Paging.
Here is my aspx Code:
<asp:Repeater ID="rp_Order" runat="server" OnItemDataBound="rp_Order_ItemDataBound">
<HeaderTemplate>
<table class="table table-responsive">
<tr >
<th style="width:20%;">Data</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<h5 style="font-weight:bold; "><%# Eval("NewsSubject") %></h5>
<p><%# Eval("NewsDate") %></p>
<img src="ImageHandler.ashx?newsid=<%# Eval("NewsID") %>" visible="<%#Eval("ImageAttachment")!=null && Eval("ImageAttachment").ToString()!=""? "true": "false" %>" class="images image-responsive myimg" />
<p ><%# System.Web.HttpUtility.HtmlDecode(Eval("NewsDescription").ToString()) %></p>
<iframe src="<%#GetUrl(Eval("youtubeurl").ToString()) %>" width="400" frameborder="0" visible="<%#Eval("youtubeurl")!=null? "true": "false" %>'"></iframe>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
<asp:Repeater ID="Repeater1" runat="server" OnItemCommand="Repeater1_ItemCommand">
<ItemTemplate>
<asp:LinkButton ID="lnkPage"
Style="padding: 8px; margin: 2px; background: lightgray; border: solid 1px #666; color: black; font-weight: bold"
CommandName="Page" CommandArgument="<%# Container.DataItem %>" runat="server" Font-Bold="True"><%# Container.DataItem %>
</asp:LinkButton>
</ItemTemplate>
</asp:Repeater>
Here is my Cs Code:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
BindData();
}
}
public void BindData()
{
List<tblLatestNew> lst_news = new List<tblLatestNew>();
lst_news = obj_news.GetLatestNews();
DataTable dtData = Utilities.ToDataTable(lst_news);
PagedDataSource pdsData = new PagedDataSource();
DataView dv = new DataView(dtData);
pdsData.DataSource = dv;
pdsData.AllowPaging = true;
pdsData.PageSize = 5;
if (ViewState["PageNumber"] != null)
pdsData.CurrentPageIndex = Convert.ToInt32(ViewState["PageNumber"]);
else
pdsData.CurrentPageIndex = 0;
if (pdsData.PageCount > 1)
{
Repeater1.Visible = true;
ArrayList alPages = new ArrayList();
for (int i = 1; i <= pdsData.PageCount; i++)
alPages.Add((i).ToString());
Repeater1.DataSource = alPages;
Repeater1.DataBind();
}
else
{
Repeater1.Visible = false;
}
rp_Order.DataSource = pdsData;
rp_Order.DataBind();
}
protected void Repeater1_ItemCommand(object source, RepeaterCommandEventArgs e)
{
ViewState["PageNumber"] = Convert.ToInt32(e.CommandArgument);
BindData();
}
Please Help me resolving this!
Currently my table has 7 Rows, so Page 1 should have 5 rows and Page 2 must have 2 Rows
Thanks in Advance

The PagedDataSource requires a page index, which starts at zero for page 1. When you change the page in Repeater1_ItemCommand the command argument is the page number, not the page index.
To get the page index just change your code in Repeater1_ItemCommand so that you subtract 1 from whatever number is passed in via e.CommandArgument, that way the proper page will display
protected void Repeater1_ItemCommand(object source, RepeaterCommandEventArgs e)
{
ViewState["PageNumber"] = Convert.ToInt32(e.CommandArgument) - 1;
BindData();
}

Related

Invalid postback or callback argument when navigating away from actively loading GridView

There are several posts on here with similar titles, but none that I have found actually exhibit the same behavior I'm seeing. I'm using buttons with MultiView as my navigation to give the appearance of tabs. The page loads, no problem. I can switch tabs, no problem. The issue I'm having occurs only when I press a different navigation button while a gridview is actively loading. If I wait for the gridview to fully load, I get no errors.
The full error I'm receiving is: Invalid postback or callback argument. Event validation is enabled using in configuration or <%# Page EnableEventValidation="true" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.
If I add the following, it does resolve my issue. However, I'm trying to avoid this if at all possible.
<%# Page ... EnableEventValidation = "false" />
default.aspx
<form id="form1" runat="server">
<table width="100%" align="center">
<tr style="background-color:#E9E9E9;">
<td>
<asp:Button Text="Tab1" BorderStyle="None" ID="Tab1Button" CssClass="Initial" runat="server"
OnClick="Tab1Button_Click" />
<asp:Button Text="Tab2" BorderStyle="None" ID="ConflictButton" CssClass="Initial" runat="server"
OnClick="ConflictButton_Click" />
<asp:Button Text="Tab3" BorderStyle="None" ID="Tab3Button" CssClass="Initial" runat="server"
OnClick="Tab3Button_Click" />
<asp:Button ID="AffiliateAddButton" runat="server" Text="Add" />
<asp:MultiView ID="MainView" runat="server">
<asp:View ID="View1" runat="server">
<table class="TabContent"><tr><td>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="true" DataSourceID="SqlDataSource1">
</asp:GridView>
</td></tr></table>
</asp:View>
<asp:View ID="View2" runat="server">
<table class="TabContent">
<tr>
<td>
View 2
</td>
</tr>
</table>
</asp:View>
<asp:View ID="View3" runat="server">
<table class="TabContent">
<tr>
<td>
View 3
</td>
</tr>
</table>
</asp:View>
</asp:MultiView>
</td>
</tr>
</table>
</form>
default.cs
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Tab1Button.CssClass = "Clicked";
MainView.ActiveViewIndex = 0;
LoadGrid();
}
}
protected override void Render(HtmlTextWriter writer)
{
// Register controls for event validation
foreach (Control c in this.Controls)
{
this.Page.ClientScript.RegisterForEventValidation(
c.UniqueID.ToString()
);
}
base.Render(writer);
}
private void LoadGrid()
{
SqlDataSource1.CancelSelectOnNullParameter = false;
GridView1.DataSourceID = null;
GridView1.DataSourceID = "SqlDataSource1";
GridView1.DataBind();
}
private void ButtonsControl(string tab)
{
if(tab == "Tab1")
{
AffiliateAddButton.Visible = true;
Tab1Button.CssClass = "Clicked";
ConflictButton.CssClass = "Initial";
Tab3Button.CssClass = "Initial";
LoadGrid();
}
if (tab == "Tab2")
{
AffiliateAddButton.Visible = false;
Tab1Button.CssClass = "Initial";
ConflictButton.CssClass = "Clicked";
Tab3Button.CssClass = "Initial";
GridView1.DataSourceID = null;
GridView1.DataBind();
}
if (tab == "Tab3")
{
AffiliateAddButton.Visible = false;
Tab1Button.CssClass = "Initial";
ConflictButton.CssClass = "Initial";
Tab3Button.CssClass = "Clicked";
GridView1.DataSourceID = null;
GridView1.DataBind();
}
}
protected void Tab1Button_Click(object sender, EventArgs e)
{
ButtonsControl("Tab1");
MainView.ActiveViewIndex = 0;
}
protected void ConflictButton_Click(object sender, EventArgs e)
{
ButtonsControl("Tab2");
MainView.ActiveViewIndex = 1;
}
protected void Tab3Button_Click(object sender, EventArgs e)
{
ButtonsControl("Tab3");
MainView.ActiveViewIndex = 2;
}
What I ended up doing was two things:
Added paging. Ideally I didn't want this in this specific scenario but limiting my page to 500 lines made it load fast enough to almost eliminate this.
Switched from multiview to frameset. Again, not an ideal option, but works in my given scenario.

Get cell value when click button in listview

I create a listview, and put button in every row of a table cell. in button click event , how to get the value in table , like Aitline, ArrCity or the index of items.
// in aspx
<asp:ListView ID="ListView1" runat="server">
<LayoutTemplate>
<ul>
<asp:PlaceHolder ID="itemPlaceholder" runat="server" />
</ul>
</LayoutTemplate>
<ItemTemplate>
<li>
<table class="table table-condensed table-striped table-hover">
<th><%#Eval("Airline")%></th>
<th><%#Eval("DepCity")%></th>
<th><%#Eval("DepTime")%></th>
<th><%#Eval("FlyTime")%> 分鐘</th>
<th><%#Eval("ArrTime")%></th>
<th><%#Eval("ArrCity")%></th>
<th class="success"><%#Eval("TotalFare")%></th>
<th><asp:Button type="submit" class="btn btn-primary btn-lg" id="PayButton" runat="server" Text="Pay" OnClick="PayButton_OnClick"/></th>
</table>
</li>
</ItemTemplate>
<EmptyDataTemplate>
<p>Nothing here.</p>
</EmptyDataTemplate>
</asp:ListView>
//in C# click event in PayButton
protected void Page_Load(object sender, EventArgs e)
{
List<Ticket> TicketList = new List<Ticket>();
this.ListView1.DataSource = TicketList;
this.ListView1.DataBind();
}
protected void PayButton_OnClick(object sender, EventArgs e)
{
// how to get table cell value here?
}
You can use the DataKeyNames attribute. For example:
<asp:ListView ID="ListView1" runat="server" DataKeyNames="ID, Name" >
and get the value this way in code-behind:
protected void PayButton_OnClick(object sender, EventArgs e)
{
ListViewItem item = (sender as LinkButton).NamingContainer as ListViewItem;
int id = (int)ListView1.DataKeys[item.DataItemIndex].Values["ID"];
string name = (string)ListView1.DataKeys[item.DataItemIndex].Values["Name"];
}

Bind RadiobuttonList inside DataList

Good morning .
I search many times before posting here .
I am working on a project like a survey [Questions and Answers]
I am able to get all questions in datalist , now i am searching a way to display the answers in Radio button list inside each question .
here is page load
protected void Page_Load(object sender, EventArgs e)
{
string CS = ConfigurationManager.ConnectionStrings["TMConnectionString"].ConnectionString;
SqlConnection con = new SqlConnection(CS);
//Getting All Questions
SqlDataAdapter dr = new SqlDataAdapter("select * from Question ", con);
DataSet ds = new DataSet();
dr.Fill(ds, "Qs");
OuterDataList.DataSource = ds.Tables["Qs"];
OuterDataList.DataBind();
}
here is page body
<body>
<form id="form1" runat="server">
<h1>Test Page</h1>
<asp:DataList ID="OuterDataList" RunAt="server">
<ItemTemplate>
<h4><%# DataBinder.Eval (Container.DataItem, "Question") %></h4>
<asp:RadioButtonList ID="RadioButtonList1" runat="server"></asp:RadioButtonList>
</ItemTemplate>
</asp:DataList>
</form>
i dont know how to bind radiobuttonlist and group the answers .
note : the common column between Question table and Answer table is Question_id
Firt will make a template like below.
<asp:DataList runat="server" ID="DataList1" RepeatDirection="Vertical"
DataKeyField="QuestionID" onitemdatabound="DataList1_ItemDataBound">
<ItemTemplate>
<table>
<tr>
<td>
<%# Eval("Question") %>
</td>
</tr>
<tr>
<td>
<asp:RadioButtonList runat="server" ID="RadioButtonList1">
</asp:RadioButtonList>
</td>
</tr>
</table>
</ItemTemplate>
After that using DataList1_ItemDataBound you can bind your answers.
protected void DataList1_ItemDataBound(object sender, DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item)
{
RadioButtonList RadioButtonList1 = (RadioButtonList)e.Item.FindControl("RadioButtonList1");
//Get questionID here
int QuestionID = Convert.ToInt32(DataBinder.Eval(e.Item.DataItem, "QuestionID"));
//pass Question ID to your DB and get all available options for the question
//Bind the RadiobUttonList here
}
}

Showing buttons if list view is empty

I have a list view which retrieves the data from sql data source. I am trying to make two buttons(Yes and No) and a label outside the list view visible only if the list view is not empty. The process is: a person enter the information into text boxes and click the button retrieve, if the entered data exists in the database, the list view shows certain information.
I have the following code:
protected void btnExistingRetrive_Click(object sender, EventArgs e)
{
if (lstExisting.Items.Count>0 )
{
lblIsITYou.Visible = true;
btnYes.Visible = true;
btnNo.Visible = true;
}
}
By default buttons and the label are not visible.
The problem is when i click on retrieve button it shows me the list view with the information but buttons a the label are still not visible. They became visible only when i double click the retrieve button. Please tell me what is my mistake?
Thank you
Use the ListView EmptyDataTemplate
<asp:ListView ID="ContactsListView"
DataSourceID="ContactsDataSource"
runat="server">
<LayoutTemplate>
<table runat="server" id="tblProducts">
<tr runat="server" id="itemPlaceholder" />
</table>
</LayoutTemplate>
<ItemTemplate>
<tr runat="server">
<td>
<asp:Label ID="FirstNameLabel" runat="Server" Text='<%#Eval("FirstName") %>' />
</td>
<td>
<asp:Label ID="LastNameLabel" runat="Server" Text='<%#Eval("LastName") %>' />
</td>
</tr>
</ItemTemplate>
<EmptyDataTemplate>
<table class="emptyTable" cellpadding="5" cellspacing="5">
<tr>
<td>
<asp:Image ID="NoDataImage"
ImageUrl="~/Images/NoDataImage.jpg"
runat="server"/>
</td>
<td>
No records available.
</td>
</tr>
</table>
</EmptyDataTemplate>
</asp:ListView>
do you bind listview before checking the items count?
Do this on postback instead of in the event.
In your Page_Load do something like this:
protected void Page_Load(object sender, EventArgs e)
{
bool visible = (lstExisting.Items.Count > 0); // assuming it's never null
lblIsITYou.Visible = visible;
btnYes.Visible = visible;
btnNo.Visible = visible;
}
If the above creates complications then do as I said first with postback:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
bool visible = (lstExisting.Items.Count > 0); // assuming it's never null
lblIsITYou.Visible = visible;
btnYes.Visible = visible;
btnNo.Visible = visible;
}
}

Repeater in ASP.net

I used repeater in asp.net. My problem is don't know how to hide a fields in repeater. There is a regular price and now price if regular price is equal to zero it will hide the fields and if not it will show the value of the regular price. i hope you can help on this.
here my code in asp:
<a href="<%=Utility.GetSiteRoot() %>/BookInfo.aspx?SKU=<%# Utility.SKUMask(Eval("lb_sku").ToString()) %>">
<img width="150px" src='<%# Eval("lb_picturepath")%>'>
</td>
<td valign="top">
<asp:Label ID="lb_titleLabel" runat="server" CssClass="center-head" Text='<%# Eval("lb_title") %>' />
<p><asp:Label ID="lb_descriptionLabel" runat="server" Text='<%# Eval("lb_description") %>' /></p>
<div class="price"><%# "Price: " + decimal.Round((decimal)Eval("lb_sellingprice"),2)%></div>
</td>
</tr>
<tr>
<td></td>
<td>
<a class="addtocart" href="<%=Utility.GetSiteRoot() %>/AddToCart.aspx?SKU=<%# Utility.SKUMask(Eval("lb_sku").ToString()) %>" >Add To Cart</a>
<a href="<%=Utility.GetSiteRoot() %>/BookInfo.aspx?SKU=<%# Utility.SKUMask(Eval("lb_sku").ToString()) %>" class="readmore">
View Details
</a></td>
thanks!
You would need to handle the OnItemDataBound event, and then change the visibility of the control. An example of this is shown below:
ASPX Page
<asp:Repeater ID="MyRepeater" OnItemDataBound="MyRepeater_OnItemDataBound" runat="server">
<ItemTemplate>
<asp:Label ID="RegularPriceLabel" runat="server" />
<br/>
<asp:Label ID="BuyNowPriceLabel" runat="server" />
</ItemTemplate>
</asp:Repeater>
Code Behind
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
MyRepeater.DataSource = GetDataSource();
MyRepeater.DataBind();
}
}
protected void MyRepeater_OnItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
// This will be your data object
MyEntity o = (MyEntity) e.Item.DataItem;
// Get the labels
Label RegularPriceLabel = (Label) e.Item.FindControl("RegularPriceLabel");
Label BuyNowPriceLabel = (Label) e.Item.FindControl("BuyNowPriceLabel");
// Only show regular price if it is set
RegularPriceLabel.Visible = (o.RegularPrice > 0);
// Populate labels
RegularPriceLabel.Text = o.RegularPrice.ToString();
BuyNowPriceLabel.Text = o.BuyNowPrice.ToString();
}
}
I would take a look at the ItemDataBound event of the Repeater. It will fire for every item in the repeater and allow you to do any code-behind (like hiding labels) more easily.
Edit: For your specific example, since you are formatting the price as well, it may be easier to just call a custom method to to render the price, like so:
ASPX:
<%#RenderPrice((decimal)Eval("lb_sellingprice"))%>
Method:
protected string RenderPrice(decimal price) {
if (price > 0) {
return "Price: $" + decimal.Round(price);
} else {
return string.Empty;
}
}
It's quick-and-dirty but it works.

Categories

Resources