How do I make timer wait until done? - c#

I have an ASP.NET website where I have to show some data on a Gridview, I need this data to be shown as fast as possible, so I decided to create a timer inside an Update panel and then Refresh the grid over and over, however I see that my timer is not waiting until it was done in order to Tick again, it's executing itself over and over, which is giving me performance issues on the database, how can I tell my timer "hey stop until this process is done, then continue".
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Timer ID="Timer1" runat="server" Interval="400" OnTick="Timer1_Tick" EnableViewState="False">
</asp:Timer>
<asp:GridView ID="gv_stats" runat="server" AutoGenerateColumns="False" BackColor="White" BorderColor="#999999" BorderStyle="Solid" BorderWidth="1px" CellPadding="3" ForeColor="Black" ShowHeaderWhenEmpty="True" GridLines="Vertical" Width="562px" OnRowDataBound="gv_stats_RowDataBound" ShowFooter="True" EnableViewState="False" >
<AlternatingRowStyle BackColor="#CCCCCC" />
<Columns>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
I tried this:
private bool is_refreshing = false;
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
}
}
protected void Timer1_Tick(object sender, EventArgs e)
{
Timer1.Enabled = false;
if(is_refreshing == false)
BindGrid();
Timer1.Enabled = true;
}
public void BindGrid()
{
is_refreshing = true;
grd.datasource = con.executedt;
grd.databind();
is_refreshing = false;
}

When you refresh the grid, you can set a private boolean variable indicating the that the grid is refreshing and before the execution of code that refreshes the grid, you can check this variable.
EDIT - Try using a session variable instead of a private variable. See updated example.
Example -
// code change starts
private bool _isGridRefreshing
{
get
{
var flag = HttpContext.Current.Session["IsGridSession"];
if(flag != null)
{
return (bool)flag;
}
return false;
}
set
{
HttpContext.Current.Session["IsGridSession"] = value;
}
}
// code change ends
protected void Timer1_Tick(object sender, EventArgs e)
{
if(_isGridRefreshing == false)
{
RefreshGrid();
}
}
private void RefreshGrid()
{
_isGridRefreshing = true;
//code to refresh the grid.
}
Note - I haven't tested the code, but it should give a fair idea of what needs to be done.

Related

First Click on ASP.NET control does not fire on click event

I'm seeing this behavior on two of my pages, but I'm just going to ask about the one that's more important to me at the moment. I have a page that loads information from a database into a ASP gridview and then allows the user to add a detail to each populated line.
The issue I'm having is that when the 'Edit' button of the gridview and then subsequently the 'Update' or 'Cancel' button, it takes two click to actually fire the onclick event. A post back does take place on the first click, but nothing actually happens.
I'm including the code that seems relevant below. The page uses a master page and there are a number of divs involved with formatting, I'm excluding those.
Gridview and related controls:
<asp:UpdatePanel runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Label Text="Plant Selector: " runat="server" />
<asp:DropDownList ID="ddlPlant" OnSelectedIndexChanged="ddlPlant_SelectedIndexChanged" runat="server" />
<asp:Button ID="btnUpdate" Text="Update" OnClick="btnUpdate_Click" runat="server" />
<p />
<asp:Label ID="lblTest" Text="" runat="server" />
<asp:Label ID="lblerror" Text="" ForeColor="Red" runat="server" />
<asp:GridView ID="gridview1" AutoGenerateColumns="false" runat="server" OnRowEditing="gridview1_RowEditing" OnRowCancelingEdit="gridview1_RowCancelingEdit" OnRowUpdating="gridview1_RowUpdating">
<Columns>
<asp:BoundField DataField="JobNum" HeaderText="Job Number" ReadOnly="true" />
<asp:BoundField DataField="ModelNum" HeaderText="Model" ReadOnly="true" />
<asp:BoundField DataField="Customer" HeaderText="Customer" ReadOnly="true" />
<asp:BoundField DataField="SchCompDate" HeaderText="Sch Comp Date" ReadOnly="true" />
<asp:TemplateField HeaderText="Details">
<EditItemTemplate>
<asp:TextBox ID="Txt" Width="98%" runat="server" />
</EditItemTemplate>
<ItemTemplate>
<asp:Label Text="Click Edit to add details of exception." runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowEditButton="true" />
</Columns>
</asp:GridView>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="gridview1" />
</Triggers>
</asp:UpdatePanel>
Sample image below:
Here is the code behind:
private string Plant { get; set; }
// This sets the default plant based off IP.
protected void Page_PreInit(Object sender, EventArgs e)
{
getPlantFromIP();
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
populateDDL();
BindData();
}
else
{
Plant = ddlPlant.SelectedValue.ToString();
}
}
// Populates the drop down.
private void populateDDL()
{
ddlPlant.Items.Add("NC");
ddlPlant.Items.Add("WA");
setPlantInDDL();
}
private void setPlantInDDL()
{
if(Plant == "WA")
{
ddlPlant.SelectedIndex = 1;
}
if (Plant == "NC")
{
ddlPlant.SelectedIndex = 0;
}
}
private void getPlantFromIP()
{
if (Request.ServerVariables["REMOTE_ADDR"] == "70.103.118.100")
{
Plant = "WA";
//ddlPlant.SelectedIndex = 1;
}
else
{
Plant = "NC";
//ddlPlant.SelectedIndex = 0;
}
}
// Database Query.
private DataTable getDataFromDatabase()
{
DataTable rTable = new DataTable();
string plant = ddlPlant.SelectedValue.ToString();
using (var conn = new MySqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["workorderConnectionString"].ConnectionString))
{
conn.Open();
using (var cmd = conn.CreateCommand())
{
try
{
cmd.CommandText = #"SELECT * FROM reportdatatables.compliance_exception_report
WHERE ExceptionNoted = '0' AND Plant = #plant";
cmd.Parameters.AddWithValue("#plant", plant);
MySqlDataReader reader = cmd.ExecuteReader();
rTable.Load(reader);
reader.Close();
cmd.Dispose();
}
catch
{
}
finally
{
conn.Close();
}
}
}
return rTable;
}
// Binds the data from the database to the gridview.
private void BindData()
{
DataTable data = getDataFromDatabase().Copy();
gridview1.DataSource = data;
gridview1.DataBind();
}
protected void ddlPlant_SelectedIndexChanged(object sender, EventArgs e)
{
//Plant = ddlPlant.SelectedValue.ToString();
BindData();
}
// On edit call.
protected void gridview1_RowEditing(object sender, GridViewEditEventArgs e)
{
}
// On cancel call.
protected void gridview1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
gridview1.EditIndex = -1;
}
protected void gridview1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
}
protected void btnUpdate_Click(object sender, EventArgs e)
{
BindData();
}
Here's what I've tried:
-A lot of posts a read saw this behavior relating to autopostback settings of controls. As you can see I'm made sure to not have any control with the autopostback set to true.
-I had some concern that the behavior might be related to the updatepanel, but removing it doesn't change the behavior at all.
-I read that having AutoEventWireup="true" in your page tag can cause this. I DO have that in my page tag, but setting it to false does not fix the issue and prevents my dropdown from being populated on page load.
-There was another post that suggested the ID of the control could be changing between page load and post back. I monitored the IDs of those controls and I do not see any change in their ID.
So all that being said, I'm hoping someone has a clue as to what I'm missing. If there is any more information I can provide that might help, please let me know.
Thank you in advance.
Try this, which will make the grid editable
protected void gridview1_RowEditing(object sender, GridViewEditEventArgs e)
{
GridView1.EditIndex = e.NewEditIndex;
BindData();
}
for cancel also
protected void gridview1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
gridview1.EditIndex = -1;
BindData();
}

Access selected Items after Postback ASP

First time posting here, so if something doesn't fit, just let me know. Also I'm not very experienced with ASP and C#, so if I just overlooked something obvious, I'm sorry.
The problem:
In the Page_Load, I call my own class MyGridViewExtension. In the constructor of this class, a Gridview will be created. The catch is: In the Headers of this Gridview is not only a Literal, but also a Listbox. The use of these Listboxes is the filtering of the displayed data, which is achieved by marking one (or more, but that doesn't matter) options of the Listbox and then clicking a button for the postback.
I tried to work with the SelectedIndexChanged Event, but that only fires AFTER the Page_Load is already completed, and as my constructor is called in it, after my GridView has already been created.
//this is the selectedIndexChanged Event Handler
private void AddToFilterList(Object sender, EventArgs e){
ListBox source=sender as ListBox;
string attributeName=source.Parent.ID; //get column name
List<string> filterList=new List<string>();
foreach(ListItem singleFilter in Source.Items){
if(singleFilter.Selected==true){
filterList.Add(singleFilter.Text);
}
}
}
//This works
The problem is, that the Constructor will complete before AddToFilterList even gets called, and afterwards it doesn't help anymore, as I need the filterList when in the constructor.
As for other code, it looks somewhat like this:
public Class MyGridViewExtension(Array Data){
checkForSelectedOptions(); //how can I have my filterList here already?
List<string> columnNames=getAllColumnNamesByCheckingData(Data);
//-create the template field to show the data
foreach (string col in columnNames)
{
TemplateField tfield = new TemplateField();
//In here, the listboxes are created
tfield.HeaderTemplate = new GridViewTemplate(ListItemType.Header, col, this);
tfield.ItemTemplate = new GridViewTemplate(ListItemType.Item, col, this);
this.Columns.Add(tfield);
}
this.DataSource=Data; //I actually transform the array to a datatable before, but that shouldn't matter here
}
protected void Page_Load(object sender, EventArgs e){
Array data=getDataFromWebserver(); //works
MyGridViewExtension thisNewGridView=new MyGridViewExtension(data);
thisNewGridView.DataBind();
divName.Controls.Add(thisNewGridView); //add the gridview to a div on the page
}
Everything works fine, getting data and displaying it, but what blocks me is that I just can't get the selected Items of the Listboxes (the filterList variable) into the Constructor.
EDIT: I should probably add that I should hold the code in the page_load as small as possible, as my job is only the Extension class and every entry in the page_load has to be made (every time) when my class is called, which should be kept to a minimum.
Thanks in advance for potential answers, comments (and edits, as my post probably isn't as good as I hope it to be).
I already edited heavily, because I overlooked something important; sorry for all those who already tried to understand/answer.
LAST EDIT: I somewhat solved the problem by re-enabling ViewState for the entire GridView, which causes some overriding problems. But those were easier to deal with than the problem described here, so that is probably the better route.
Thanks to everybody who gave tips.
protected void Page_Load(object sender, EventArgs e)
{
Array data;
if (IsPostback)
{
data = Session["data"] == null ? getDataFromWebserver() : Session["data"] // if session is null, go get data, otherwise use session variable.
}
else
{
// Go get you data, since it is a first load or a refresh
// once you have data - put it in session
Session["data"] = getDataFromWebserver();
data = Session["data"];
}
MyGridViewExtension thisNewGridView=new MyGridViewExtension(data);
thisNewGridView.DataBind();
divName.Controls.Add(thisNewGridView); //add the gridview to a div on the page
// No you can do whatever you need to do...
// some code
}
try this, see if it helps.
This works. It loads a dropdown list from which you may select an item, upon which data is filtered. This is what you are describing or at least the way I understand it. Dropdown maybe substituted for your listboxes, however, I think ddl's are cleaner looking (personal preference though).
Code-behind:
using xxx.DB;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace xxx_Internal_SQL.PostTree.Reports.FailedLeads
{
public partial class Default : System.Web.UI.Page
{
private string programName = "Post_Reports_FailedLeads";
private List<string> lstTransactionSource = new List<string>();
private List<string> lstTransactionSubSource = new List<string>();
private List<string> lstTransactionRef = new List<string>();
private List<string> lstTransactionSubRef = new List<string>();
private List<string> lstIsTest = new List<string>();
private string TransactionSource = string.Empty;
private string TransactionSubSource = string.Empty;
private string TransactionRef = string.Empty;
private string TransactionSubRef = string.Empty;
private string IsTest = string.Empty;
protected void Page_Load(object sender, EventArgs e)
{
try
{
if (IsPostBack)
{
if (Session["myDataView"] != null)
BindDataToGV((DataView)Session["myDataView"]);
}
else
{
FillDDL();
ViewState["sortOrder"] = "";
Session["OriginalDT"] = null;
}
}
catch (Exception ex)
{
Global.ReportProblem(ex, programName, "Page_Load");
}
}
private void FillTable(string sortExp, string sortDir)
{
try
{
ClearGV();
object myData;
DataTable dtData = GetData();
Session["OriginalDT"] = dtData;
if (sortExp != string.Empty)
{
DataView myDataView = new DataView();
myDataView = dtData.AsDataView();
myDataView.Sort = string.Format("{0} {1}", sortExp, sortDir);
dtData = myDataView.ToTable();
Session["OriginalDT"] = dtData;
Session["myDataView"] = myDataView;
myData = myDataView;
}
BindDataToGV(dtData);
}
catch (Exception ex)
{
Global.ReportProblem(ex, programName, "FillTable");
}
}
private DataTable GetData()
{
return GetData(db, values);
}
private void ClearGV()
{
gvTransactions.DataSource = null;
gvTransactions.DataBind();
}
private void BindDataToGV(object obj)
{
gvTransactions.DataSource = obj;
gvTransactions.DataBind();
}
private DataTable GetData(Database db, SortedList<string, string> values)
{
DataTable dt = null;
try
{
if (db.GenericSP("sp_xxx", values, true))
return db.Output_DT;
}
catch (Exception ex)
{
Global.ReportProblem(ex, programName, "GetData");
}
return dt;
}
protected void lnkFindTransactions_Click(object sender, EventArgs e)
{
try
{
if (ddlAffiliates.SelectedIndex > 0) FillTable("", "");
}
catch (Exception ex)
{
Global.ReportProblem(ex, programName, "lnkFindTransactions_Click");
}
}
protected void gvTransactions_Sorting(object sender, GridViewSortEventArgs e)
{
FillTable(e.SortExpression, sortOrder);
}
protected void gvTransactions_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
gvTransactions.PageIndex = e.NewPageIndex;
if (Session["OriginalDT"] != null)
BindDataToGV((DataTable)Session["OriginalDT"]);
}
public string sortOrder
{
get
{
if (ViewState["sortOrder"].ToString() == "desc")
{
ViewState["sortOrder"] = "asc";
}
else
{
ViewState["sortOrder"] = "desc";
}
return ViewState["sortOrder"].ToString();
}
set
{
ViewState["sortOrder"] = value;
}
}
private void FillDDL()
{
if (db.GetRecords("sp_xxx"))
{
DataTable dt = db.Output_DT;
ddlAffiliates.Items.Add(new ListItem("Select...", ""));
foreach (DataRow dr in dt.Rows)
ddlAffiliates.Items.Add(new ListItem(dr["name"].ToString(), dr["aid"].ToString()));
}
}
}
}
front-end:
<asp:Table runat="server">
<asp:TableRow>
<asp:TableCell Width="100px" HorizontalAlign="Right">Date: </asp:TableCell>
<asp:TableCell Width="200px" HorizontalAlign="Left">
<ajaxToolkit:CalendarExtender runat="server" Animated="true"
ID="extCalendarEnd" TargetControlID="txtDateEnd">
</ajaxToolkit:CalendarExtender>
<asp:TextBox ID="txtDateEnd" runat="server" Width="180px"></asp:TextBox>
</asp:TableCell>
<asp:TableCell Width="75px" HorizontalAlign="Left">Seller: </asp:TableCell>
<asp:TableCell Width="200px" HorizontalAlign="Left">
<asp:DropDownList ID="ddlAffiliates" runat="server" Enabled="false"></asp:DropDownList>
</asp:TableCell>
<asp:TableCell HorizontalAlign="Left">
<asp:UpdatePanel runat="server" UpdateMode="Always" ID="upnlFind" ChildrenAsTriggers="true">
<ContentTemplate>
<asp:LinkButton ID="lnkFindTransactions" runat="server" CssClass="linkButton" OnClick="lnkFindTransactions_Click" Text="Find" />
</ContentTemplate>
</asp:UpdatePanel>
</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell ColumnSpan="5">
<hr />
<asp:Panel runat="server" Width="600px" Height="100%">
<asp:Panel runat="server" ID="pnlGridview" Width="500px" Style="margin: 0px auto 0px auto;">
<asp:GridView runat="server" ID="gvTransactions"
GridLines="None" AllowPaging="True"
AllowSorting="True" PageSize="25"
CellPadding="4" ForeColor="#333333"
Width="600px" OnSorting="gvTransactions_Sorting"
OnPageIndexChanging="gvTransactions_PageIndexChanging"
RowStyle-Wrap="false" CssClass="gvTransactions">
<AlternatingRowStyle BackColor="White" ForeColor="#284775" />
<PagerSettings Position="TopAndBottom" Mode="NumericFirstLast" />
<PagerStyle HorizontalAlign="Left" />
<EditRowStyle BackColor="#999999" />
<FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
<RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
<SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
<SortedAscendingCellStyle BackColor="#E9E7E2" />
<SortedAscendingHeaderStyle BackColor="#506C8C" />
<SortedDescendingCellStyle BackColor="#FFFDF8" />
<SortedDescendingHeaderStyle BackColor="#6F8DAE" />
</asp:GridView>
</asp:Panel>
</asp:Panel>
</asp:TableCell>
</asp:TableRow>
</asp:Table>
as a closing note. It is not a perfect all addressing code, but it does what it was designed to do. Feel free to build on-top of it or modify any part of it.

asp.net Gridview checkbox - false value

I have read several other questions similar to this, and it looks to be a databinding issue. My issue somehow differs as I do not bind the data on page load. The data is bound when a selection is made from another table on the same page.
For example, my page has 3 tables (one with no value initially):
Sessions - Each session has a session date and a list of attendees
PlayersList - Contains records for all players
Attendees - Displays a list of players for a SELECTED session, from the Sessions table
Each time I select a session, and then check the Attendees checkbox, the value is always 'False'.
Thanks in advance
Here's my code.
Matches.aspx.cs
public partial class Matches : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void GridSessionsList_SelectedIndexChanged(object sender, EventArgs e)
{
}
protected void GridAttendees_SelectedIndexChanged(object sender, EventArgs e)
{
// this will remove an attendee from the list
}
protected void ButtonUpdatePaid_Click1(object sender, EventArgs e)
{
Session editSession = new Session();
foreach (GridViewRow row in GridAttendees.Rows)
{
editSession.Date = Convert.ToDateTime(GridSessionsList.SelectedValue);
int PlayerID = Convert.ToInt32(row.Cells[1].Text);
bool Paid = Convert.ToBoolean(row.FindControl("Chk") as TextBox);
editSession.UpdateAttendeeList(PlayerID, Paid);
}
}
protected void GridPlayersList_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
Session editSession = new Session();
editSession.Date = Convert.ToDateTime(GridSessionsList.SelectedValue);
int PlayerID = Convert.ToInt32(GridPlayersList.SelectedRow.Cells[1].Text);
editSession.UpdateAttendeeList(PlayerID);
GridAttendees.DataBind();
LabelError.Text = "Player has been added to the game on .";
}
catch
{
LabelError.Text = "Something went wrong.. Ensure you have a game selected.";
}
}
public void Chk_OnCheckedChanged(object sender, EventArgs e)
{
}
And here's the Attendees GridView extract from the aspx page:
<asp:GridView ID="GridAttendees" runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSource2" CssClass="Table" DataKeyNames="PlayerID" OnSelectedIndexChanged="GridAttendees_SelectedIndexChanged">
<Columns>
<asp:CommandField ShowSelectButton="True" SelectText="Select"/>
<asp:BoundField DataField="PlayerID" HeaderStyle-CssClass = "hideGridColumn" ItemStyle-CssClass="hideGridColumn" HeaderText="PlayerID" SortExpression="PlayerID" InsertVisible="False" ReadOnly="True" >
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="Chk" runat="server" OnCheckedChanged="Chk_OnCheckedChanged" AutoPostBack="True" Checked='<%# Bind("Paid") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<HeaderStyle CssClass="TableHeader" />
<SelectedRowStyle BackColor="Silver" />
</asp:GridView>
I think you are casting your CheckBox as a TextBox ?
Here:
bool Paid = Convert.ToBoolean(row.FindControl("Chk") as TextBox);
Try this:
CheckBox cb = (CheckBox)row.FindControl("Chk");
bool Paid = cb.Checked;

ASP .NET - Setting the value of a DetailsView TextBox

I am attempting to use the code-behind (Page_Load or PreRender) to set a date-time textbox in a DetailsView so that it defaults to a current date-time.
What I have attempted is (one of many variations):
protected void DetailsView2_PreRender(object sender, EventArgs e)
{
((TextBox)DetailsView2.FindControl("date_time")).Text =
DateTime.Now.ToString("d");
}
But all that I get is a 'NullReferenceException' error.
What I am doing wrong?
You can use detailsview controls DataBound event to set a value within your detailsview like that :
<asp:Label ID="DetailsView2" runat="server" OnDataBound="DetailsView2_DataBound">
</asp:Label>
Code Behind :
protected void DetailsView2_DataBound(object sender, EventArgs e)
{
DetailsView myDetailsView = (DetailsView)sender;
if(myDetailsView.CurrentMode == DetailsViewMode.Edit)
{
((TextBox)myDetailsView.FindControl("date_time")).Text = DateTime.Now.ToString("d");
}
}
To add to what Canavar suggested:
For use on a DetailsView assign like this:
<asp:DetailsView ID="DetailsView2" runat="server" AutoGenerateRows="False"
CellPadding="4" DataKeyNames="details_id" DataSourceID="SqlDataSource4"
DefaultMode="Insert" ForeColor="#333333" GridLines="None" Height="50px"
Width="125px"
AllowPaging="True" OnPreRender="DetailsView2_DataBound">
And then in the code behind:
protected void DetailsView2_DataBound(object sender, EventArgs e)
{
DetailsView myDetailsView = (DetailsView)sender;
//Edit
if (myDetailsView.CurrentMode == DetailsViewMode.Edit)
{
((TextBox)myDetailsView.FindControl("TextBox2")).Text = DateTime.Now.ToString("g");
}
//Insert
else if (myDetailsView.CurrentMode == DetailsViewMode.Insert)
{
((TextBox)myDetailsView.FindControl("TextBox2")).Text = DateTime.Now.ToString("M/d/yyyy HH:mm");
}
}

ASP.NET GridView, enabling/disabling buttons after paging

I have successfully implemented my GridView now, but, as always, the whole ASP.NET life cycle thing is bothering me. I can't figure out why this doesn't work. I have bound the GridView's OnPageIndexChanged as such:
protected void GridView_PageIndexChanged(object sender, EventArgs e)
{
// Enable/disable the previous/next buttons.
LinkButton btnNextPage = (LinkButton)gvTable.BottomPagerRow.FindControl("btnNextPage");
LinkButton btnPreviousPage = (LinkButton)gvTable.BottomPagerRow.FindControl("btnPreviousPage");
btnNextPage.Enabled = false;
btnPreviousPage.Enabled = false;
}
This is my ASCX:
<asp:GridView ID="gvTable" runat="server" ShowHeader="true" PageSize="1"
AllowPaging="true" AllowSorting="true" DataSourceID="dsLinqActivities"
AutoGenerateColumns="false" OnRowDataBound="GridView_DataBound"
OnPageIndexChanged="GridView_PageIndexChanged">
<Columns>
<asp:BoundField DataField="Edited" HeaderText="Date" />
<asp:BoundField DataField="Status" HeaderText="Status" />
<asp:BoundField DataField="Activity" />
</Columns>
<PagerSettings Position="Bottom" Visible="true" />
<PagerStyle CssClass="pager" />
<PagerTemplate>
<asp:LinkButton ID="btnPreviousPage" class="navbtn prev left"
runat="server" CommandName="Page" CommandArgument="Prev">
<span>Newer activities</span></asp:LinkButton>
<asp:LinkButton ID="btnNextPage" class="navbtn next right"
runat="server" CommandName="Page" CommandArgument="Next">
<span>Older activities</span></asp:LinkButton>
</PagerTemplate>
</asp:GridView>
I debug my application and see that the code is being run and does the right thing but for some reason when the control is rendered, both of the buttons are always enabled. What am I doing wrong here?
If I were you, I would code it like this in the "GridView_PageIndexChanged" method
(gvTable.BottomPagerRow.FindControl("btnNextPage") as LinkButton).Enabled = true/false;
Edit:Can you also try adding a setter ?
set
{
gvTable.BottomPagerRow.FindControl("btnNextPage") as LinkButton =value;
}
Edit: OK my friend, I finally worked out a solution. May be not very elegant,but it works and I tested it. There are a few things to take care of:
1. We are having a "Prev" and a "Next" button and we got to handle "OnCommand" events for those since we are using our own Pager Template
2. We would have to bind data after we handle our OnCommand event.
I have a static List<String> which I populated during GET with random strings (Courtesy: http://www.kivela.be/index.php/2007/06/19/how-to-generate-a-random-string-in-c-20/) and bound them to my grid. You can substitute your own datasource here.Also, we have to change the grid's page index manually in our OnCommand Event.
Here is my aspx/ascx grid
<asp:GridView ID="GridView1" runat="server" OnRowDataBound="GridView_DataBound"
AllowPaging="true" PagerSettings-Mode="NextPrevious" PagerSettings-Position="Bottom" PageSize="10"
OnPageIndexChanged="GridView_PageIndexChanged">
<PagerSettings Position="Bottom" Visible="true" />
<PagerStyle CssClass="pager" />
<PagerTemplate>
<asp:LinkButton ID="btnPreviousPage" OnCommand="ChangePage"
runat="server" CommandName="Prev" Text="prev">
</asp:LinkButton>
<asp:LinkButton ID="btnNextPage" OnCommand="ChangePage"
runat="server" CommandName="Next" Text="next">
</asp:LinkButton>
</PagerTemplate>
</asp:GridView>
and here is the codebehind
public partial class TestPage : System.Web.UI.Page
{
private static Random _random = new Random();
static List<string> lst = new List<string>();
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
for (int i = 1; i <= 30; i++)
{
lst.Add(RandomString(i));
}
GridView1.DataSource = lst;
GridView1.DataBind();
SetPageNumbers();
}
}
private void SetPageNumbers()
{
if (GridView1.PageIndex == 0)
{
(GridView1.BottomPagerRow.FindControl("btnPreviousPage")as LinkButton).Enabled = false;
}
if(GridView1.PageIndex ==GridView1.PageCount-1)
{
(GridView1.BottomPagerRow.FindControl("btnNextPage") as LinkButton).Enabled = false;
}
}
protected void ChangePage(object sender, CommandEventArgs e)
{
switch (e.CommandName)
{
case "Prev":
GridView1.PageIndex = GridView1.PageIndex - 1;
break;
case "Next":
GridView1.PageIndex = GridView1.PageIndex + 1;
break;
}
GridView1.DataSource = lst;
GridView1.DataBind();
SetPageNumbers();
}
public static string RandomString(int size)
{
StringBuilder builder = new StringBuilder();
for (int i = 0; i < size; i++)
{
//26 letters in the alfabet, ascii + 65 for the capital letters
builder.Append(Convert.ToChar(Convert.ToInt32(Math.Floor(26 * _random.NextDouble() + 65))));
}
return builder.ToString();
}
}
Hope this helps
Is there any chance your CSS is setting the enabled property?
I duplicated your code without the CSS and it works fine for me.
How about posting your css?

Categories

Resources