I have a View button on my webpage. As soon as a user clicks on this button, through a web service data is fetched and then data is bound to grid view. But when the grid view loads it only shows the number of rows mentioned in PageSize property of the grid and does not show page numbers.
private void FetchData(ref DataTable dt)
{
string s_strResult = "";
string s_strQuery = "";
string s_strQueryType = "";
try
{
grdSearchResult.DataSource = dt.DataSet.Tables["Result"];
grdSearchResult.DataBind();
tblSearchResult.Visible = true;
lblSearchResult.Text = "Total Items:" + dt.DataSet.Tables["Result"].Rows.Count;
}
}
The Result DataSet contains 5000 rows with 30 columns each. When the gridView loads all I can see is just 100 records (as PageSize=100). How can I page the results? The data needs to be fetched at button click only. The code for gridView page index change is as follows:
protected void grdSearchResult_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
try
{
grdSearchResult.PageIndex = e.NewPageIndex;
grdSearchResult.DataBind();
}
catch (Exception ex)
{
DisplayMessage(GlobalClass.enumMsgType.Error, ex.Message);
}
}
Hello Rishik please check below link for gridview paging:
http://www.codeproject.com/Articles/816953/How-To-Implement-Paging-in-GridView-Control-in-ASP
http://www.c-sharpcorner.com/UploadFile/rohatash/gridview-paging-sample-in-Asp-Net/
You can store your data in a Viewstate or Session variable, I recommend to use a property as wrapper like this:
private DataTable dtStored
{
get { return (ViewState["dt"] == null) ? null : (DataTable)ViewState["dt"]; }
set { ViewState["dt"] = value; }
}
now you can bind your DataTable and save it in the property:
private void FetchData(ref DataTable dt)
{
string s_strResult = "";
string s_strQuery = "";
string s_strQueryType = "";
try
{
dtStored = dt.DataSet.Tables["Result"];
grdSearchResult.DataSource = dtStored;
grdSearchResult.DataBind();
tblSearchResult.Visible = true;
lblSearchResult.Text = "Total Items:" + dt.DataSet.Tables["Result"].Rows.Count;
}
}
and in the IndexPageChanging method just add a line:
protected void grdSearchResult_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
try
{
grdSearchResult.DataSource = dtStored;
grdSearchResult.PageIndex = e.NewPageIndex;
grdSearchResult.DataBind();
}
catch (Exception ex)
{
DisplayMessage(GlobalClass.enumMsgType.Error, ex.Message);
}
}
If your data is too large maybe it could be better to store it in a Session variable than in a Viewstate, because the second one is going to travel from the Client to the Server and from the Server to the Client in every Postback while you stay in the same page or until you set the variable to null
Related
I have a GridView and I'm performing a bulk update for only one column with textbox. But before update I need to check the values of that textbox for entire gridview and if the values aren't changed I need to provide an alert stating "Make change to field to update".
Can anyone suggest me some options?
protected void btnUpdate_Click(object sender, EventArgs e)
{
try
{
foreach (GridViewRow row in gvDetails.Rows)
{
string strID = ((Label)row.FindControl("lblID")).Text;
string strGroup = ((Label)row.FindControl("lblGrp")).Text;
string strValue = ((TextBox)row.FindControl("txtValue")).Text;
{
//my update query
}
}
}
catch (Exception ex)
{
}
}
A much simpler method will be to add an asp:HiddenField to your ItemTemplate and compare the value for each row.
<asp:HiddenField ID="" runat="server" Value='<%# Eval("blah") %>'></asp:HiddenField>
Now all you need is to compare that value with the textbox value in each row in code-behind like this.
protected void btnUpdate_Click(object sender, EventArgs e)
{
try
{
var isAnyRowUpdated = false;
foreach (GridViewRow row in gvDetails.Rows)
{
string strID = ((Label)row.FindControl("lblID")).Text;
string strGroup = ((Label)row.FindControl("lblGrp")).Text;
string strValue = ((TextBox)row.FindControl("txtValue")).Text;
string strOldValue = ((HiddenField)row.FindControl("hdnOldValue")).Value;
if (strValue != strOldValue)
{
isAnyRowUpdated = true;
//update procedure here.
}
}
//now check if the flag is still false
//that means no rows are changed
if(!isAnyRowUpdated)
{
//alert no rows are updated
}
}
catch (Exception ex)
{
}
}
I hope the code is self explanatory.
You can try to use DataGridView.RowValidating Event and check if IsCurrentRowDirty Property is changed
IsCurrentRowDirty Property Gets a value indicating whether the current
row has uncommitted changes.
EDIT:-
The above works in Winforms; in Asp.net there is no such method, you have to load the data in a object and then you have to validate.
You can check Updating Only Changed Rows Using GridView Control
The basic thing to do here to load your original data into a DataTable and then compare the GridView rows, one by one in a loop for that particular Column, which in your case is the TextBox column. For comparing the DataTable with the GridView, you can try something like this :
foreach (GridViewRow row in Grd.Rows)
{
TextBox txtAmt = (TextBox)row.FindControl("txtAmount");
string Id = Grd.DataKeys[row.RowIndex].Value.ToString();
for (int i = 0; i < dt.Rows.Count; i++)
{
if (Id == dt.Rows[i]["ID"].ToString())
{
//do your logic here.
}
}
}
Hope this helps.
As per the conversation, I have provided some pseudo logic. You can implement your own code using this.
protected void btnUpdate_Click(object sender, EventArgs e)
{
try
{
DataTable dt = LoadData(); //Load the data from DB
EnumerableRowCollection<DataRow> enumerableDt = dt.AsEnumerable();
foreach (GridViewRow row in gvDetails.Rows)
{
string strID = ((Label)row.FindControl("lblID")).Text;
string strGroup = ((Label)row.FindControl("lblGrp")).Text;
string strValue = ((TextBox)row.FindControl("txtValue")).Text;
DataRow dr = enumerableDt.Where(x => x.Field<string>("ID") == strID).FirstOrDefault(); //Change your condition accordingly
if (dr["Value"].ToString().ToUpper() != strValue.Trim().ToUpper()) //Change your condition here
{
//Do your updated data logic here
}
else
{
//Do your not updated data logic here
}
}
}
catch (Exception ex)
{
}
}
Check them against the datakey value for the corresponding item.
<MasterTableView DataKeyNames="Response, ...
foreach (GridDataItem item in FTReport.MasterTableView.Items)
{
string ResponseValue = tbResponse.Text;
if (item.GetDataKeyValue("Response").ToString() != ResponseValue)
{
do something;
}
}
use onrowdatabound property of gridview. Inside it, use:
protected void GridLocation_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow &&
(e.Row.RowState & DataControlRowState.Edit) == DataControlRowState.Edit)
{
// here you can check your textbox values
}
}
I would like to assign number of rows to my GridView.
Example:
GridView1.Rows.Count = 500;
More My code
using (CEntities context = new CEntities())
{
Users = context.Procedure(0,10).ToList<Procedure_Result>();
}
GridView1.UseAccessibleHeader = true;
GridView1.DataSource = Users;
GridView1.DataBind();
I will explain this problem much more clearly:
I wrote this context.Procedure(0,10) I get only 10 elements and one page. Normally I have 500 elements (rows). I search place where can I write value of all my rows. Otherwise I will not see other my pages.
Example of my problem in JTable Grid -> StudentsCount (I want make similar version in GridView to make this GridView very fast. Simple way I know. )
http://jtable.org/Tutorials/UsingWithAspNetWebFormsPageMethods
[WebMethod(EnableSession = true)]
public static object StudentList(int jtStartIndex, int jtPageSize, string jtSorting)
{
try
{
//Get data from database
int studentCount = Repository.StudentRepository.GetStudentCount();
List<Student> students = Repository.StudentRepository.GetStudents(jtStartIndex, jtPageSize, jtSorting);
//Return result to jTable
return new { Result = "OK", Records = students, TotalRecordCount = studentCount };
}
catch (Exception ex)
{
return new { Result = "ERROR", Message = ex.Message };
}
}
If you want to apply paging in your GridView.
You can try this.
Markup
<asp:GridView ID="gridview" AllowPaging="true" PageSize="10" OnPageIndexChanging="gridview_PageIndexChanging" runat="server" />
Code behind
protected void gridview_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
//Fill grid here
gridview.PageIndex = e.NewPageIndex;
gridview.DataBind();
}
My problem is that when i display data in listview for first time then it show correctly but when i display data second time then listview does not update the data correctly. I have made a function for databinding with listview which i have called in pageLoad and some other method.
Can anyone please give me a solution about this ?
I have also uploaded my source code for more detail.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LoadDataIntoListView();
}
}
protected void LoadDataIntoListView()
{
Users objQuery = new Users();
string adminID = "Here is my query to get the data from MS-SQL";
objQuery.ExecuteSql(str);
if (objQuery.RowCount > 0)
{
Title = "Row affected";
lstAppointments.Items.Clear();
lstAppointments.DataSource = objQuery.DefaultView;
lstAppointments.DataBind();
}
else
{
Title = "None Row affected";
}
}
protected void btnDelete_Click(object sender, EventArgs e)
{
string caseID = (string)Session["caseID"];
//string updateQuery = "update Cases set sCaseStatus='cancel' where iCaseID= '" + caseID + "'";
Cases objCases = new Cases();
objCases.LoadByPrimaryKey(Convert.ToInt32(caseID));
if (String.Equals(objCases.SCaseStatus, "cancel"))
{
Page.Title = "No Update";
ModalPopupExtender1.Hide();
}
else
{
objCases.SCaseStatus = "cancel";
objCases.Save();
Page.Title = "No Update";
ModalPopupExtender1.Hide();
lstAppointments.Items.Clear();
LoadDataIntoListView();
}
}
Thanks in advance.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LoadDataIntoListView();
}
}
You are binding data in not Postback. That means it does not binds data when you postback to same page. If you want to bind that on every page load, call the function LoadDataIntoListView() in Page_Load
So finally.. I have my repeater working as I want it to be full of buttons, radio button, image buttons, update panels, AJAX modal popups and a heavy code behind each event.
found out that my repeater getting very slow when the items exceeds 20, so I used paging as a solution. the problem is when I do changes and move on to the next page, all changes are gone when getting back to the previous page. (checked radios, labels, etc all back to normal state).
please help, my system is in production now.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
loadTasks();
}
void loadTasks()
{
string evalidxxx = Request.QueryString["eval_id"].Trim().Replace(" ", "");
SqlConnection conn = new System.Data.SqlClient.SqlConnection(ConfigurationManager.ConnectionStrings["GappConnectionString2"].ConnectionString);
try
{
conn.Open();
SqlDataAdapter sqlAdapter = new SqlDataAdapter("SELECT Prog_Task_link.pt_seq, Tasks.task_name, Tasks.task_id FROM Tasks INNER JOIN Prog_Task_link ON Tasks.task_id = Prog_Task_link.task_id INNER JOIN Programs ON Prog_Task_link.prog_id = programs.prog_id INNER JOIN Data_Tracker_prepare ON Programs.prog_id = Data_Tracker_prepare.dtpre_prog_id WHERE Data_Tracker_prepare.eval_id =" + evalidxxx, conn);
System.Data.DataTable dt = new System.Data.DataTable();
sqlAdapter.Fill(dt);
PagedDataSource objPds = new PagedDataSource();
objPds.DataSource = dt.DefaultView;
objPds.AllowPaging = true;
objPds.PageSize = 10;
objPds.CurrentPageIndex = CurrentPage;
lblCurrentPage.Text = "Page: " + (CurrentPage + 1).ToString() + " of "
+ objPds.PageCount.ToString();
//Disable Prev or Next buttons if necessary
LinkPrevPage.Enabled = !objPds.IsFirstPage;
LinkNextPage.Enabled = !objPds.IsLastPage;
rptr1.DataSource = objPds;
rptr1.DataBind();
}
catch (SqlException ex)
{
Response.Write(ex.Message);
}
finally { conn.Close(); }
}
public int CurrentPage
{
get
{
// look for current page in ViewState
object o = this.ViewState["_CurrentPage"];
if (o == null)
return 0; // default to showing the first page
else
return (int)o;
}
set
{
this.ViewState["_CurrentPage"] = value;
}
}
protected void LinkPrevPage_Click(object sender, EventArgs e)
{
CurrentPage -= 1;
loadTasks();
}
protected void LinkNextPage_Click(object sender, EventArgs e)
{
CurrentPage += 1;
loadTasks();
}
if you are using .net 4.0 you can use EnablePersistedSelection="True"
sorry to say but this can not be done..
When you are in page one, the rest pages are not actual exists in repeater.
after paging to next page next data will be load so previous data will be reset
i mean to say, When you ask to select all radios, buttons,check boxes are mean what you see. After you change page the other controls are set to default (probably unchecked or reset)
So re design your user interface for what you want to do. And as my suggestion take another button to save the current state of the page.. and then go to next page..
anything other that i can help ??
I have one Telerik RadGrid. Using a method I am filling the grid. I have enabled the paging property. I have used ItemTemplate-->ImageButton for delete and edit options. I have set page size as 10. Page load time is working properly and populating the grid. After inserting the 11th row the pagination starts and it will show in the next page with one record. But when I am deleting the 11th row the grid becomes blank. I have used dataset to bind the records.
radgrid.DataBind();
dsDataset.Dispose();
But its item.count is 0. What is the reason?
protected void Page_Load(object sender, EventArgs e)
{
try
{
if (!IsPostBack)
{
PopulatePackage();
}
}
catch (Exception ex)
{
lblMessage.Text = objUtl.GetErrorMessage(ex, this);
lblMessage.Visible = true;
protected void gvPackage_NeedDataSource(object source, GridNeedDataSourceEventArgs e)
{
try
{
SqlHelper objSQL = new SqlHelper();
DataSet dsPackage = new DataSet();
dsPackage = objSQL.ExecuteDataset("AL_PackageType_List_Retrieve", objUtl.NumericEntry(Session["LocationId"].ToString()));
gvPackage.DataSource = dsPackage.Tables[0];
dsPackage.Dispose();
//PopulatePackage();
}
catch (Exception ex)
{
lblMessage.Text = objUtl.GetErrorMessage(ex, this);
lblMessage.Visible = true;
}
}
private void PopulatePackage()
{
try
{
lblMessage.Text = string.Empty;
SqlHelper objSQL = new SqlHelper();
DataSet dsPackage = new DataSet();
dsPackage = objSQL.ExecuteDataset("AL_PackageType_List_Retrieve", objUtl.NumericEntry(Session["LocationId"].ToString()));
gvPackage.DataSource = null;
gvPackage.DataSource = dsPackage.Tables[0];
gvPackage.DataBind();
//dsPackage.Dispose();
if (gvPackage.Items.Count <= 0)
{
lblMessage.Text = "No Package Details Found...";
gvPackage.Visible = false;
}
else
{
gvPackage.Visible = true;
}
}
catch (Exception ex)
{
lblMessage.Text = objUtl.GetErrorMessage(ex, this);
lblMessage.Visible = true;
}
}
Okay as far as I am understanding it, You have a radgrid in which you have allowed paging and set the page size to 10. Upon inserting the 11th record a new page is shown with that 11th record. And when that 11th record is deleted you are viewing a blank page, instead of showing the page having record from 1 to 10. I hope I am right here.
Anyway. I guess the problem is that the Radgrid is not having the data for the page you are viewing now.
There is an event in RadGrid named NeedDataSource. This Event is fired up whenever the RadGrid needs to display the data. You can call the Binding logic in this event and see if it works for you.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindGrid();
}
}
private void BindGrid()
{
RadGrid1.DataSource = "BindingSource";
RadGrid1.DataBind();
}
protected void RadGrid1_NeedDataSource(object sender, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
{
BindGrid();
}
See if this works for you..