I have a datagrid where a row can be deleted (using ajax). I'm have problem with the pager in the following scenario:
Lets say my PageSize is 10, I have 101 rows so that's 11 pages with the last page with an single element. Let no assume that I'm on page 10 (PageIndex=9) and delete a row. Then I go to the 11'th page (who's now empty and doesn't really exist). ASP now shows me the EmptyDataTemplate and no pager so I can't go back.
My approach (which isn't working) is to detect this scenario and step one page back:
public void Bind()
{
gridMain.DataBind();
}
public void SetPage(int page)
{
gridMain.PageIndex = page;
gridMain.DataBind();
}
protected void ldsGridMain_Selecting(object sender, LinqDataSourceSelectEventArgs e)
{
selectArgs = e;
e.Result = (new EnquiryListController()).GetEnquiryList(OnBind(this), supplier);
}
protected void ldsGridMain_Selected(object sender, LinqDataSourceStatusEventArgs e)
{
totalRows = selectArgs.Arguments.TotalRowCount;
//Detect if we need to update the page:
if (gridMain.PageIndex > 0 && (gridMain.PageSize * gridMain.PageIndex + 1) > totalRows) SetPage(gridMain.PageIndex - 1);
}
protected void gridMain_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
SetPage(e.NewPageIndex);
}
I can see that SetPage is called with the the right page index, but the databind doesn't seem to called as I still get the EmptyDataTemplate.
When you delete the item, you need to rebind the data, so that the pager resizes.
Not just call databind, you have to reset the datasource and call databind. It doesn't keep the data in the datasource between post backs.
Before you do that, make sure you reset the pageIndex to one that is in scope on the new set.
SetPage(gridMain.PageIndex - 1) might be incorrect. You have to calculate what the last page will be for the current row count. Current PageIndex-1 can be out of range.
Rebind the grid in SetPage with updated datasource and set pageindex. check if RecordCount/PageSize is less than NumberofPages in pager or current Page index then decrease the page index as per RecordCount/PageSize .
Can't you just use something like:
public void SetPage(int page)
{
gridMain.PageIndex = Math.Max(page, gridMain.PageCount);
gridMain.DataBind();
}
Related
I am trying to find a way to page through a gridview table by year. In my database I have a "season" field and I want all of the data from 2014 shown on one page, all the data from 2013 on another, etc. This would also require different numbers of rows based on the year.
Here is how I would do it. I wouldn't use the default paging of the gridview to handle this. Instead, I would buttons (or linkbuttons) to imitate the paging so that you control the paging. This way, you will be able to handle the change in year as well as control what is displayed.
The Steps are as follows:
1) Add your gridview to the page with a big page size just to display everything
<asp:GridView ID="dgvRequests" runat="server" AutoGenerateColumns="False" PageSize="9999"> </asp:GridView>
2) Bind the Per Year data to it in the code behind since you are display everthing per year in your page load. As well as store a variable to track the year
public int CurrentYear
{
get {
if(ViewState["currentYear"] != null)
return (int)ViewState["currentYear"];
return 2014; //Default
}
set {
_ViewState["currentYear"]= value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
dgvRequests.DataSource = GetYearData(CurrentYear); //Or Your variable
dgvRequests.DataBind();
}
}
3) Make controls to control the page. I used Link Buttons
<asp:LinkButton ID="lbtnPrevious" runat="server" OnClick="lbtnPrevious_Click"></asp:LinkButton>
<asp:LinkButton ID="lbtnlNext" runat="server" OnClick="lbtnlNext_Click"></asp:LinkButton>
4) On the click event, control the paging of the gridviews via the click event
protected void lbtnlNext_Click(object sender, EventArgs e)
{
dgvRequests.DataSource = GetYearData(++CurrentYear); //Or Your variable
dgvRequests.DataBind();
}
protected void lbtnPrevious_Click(object sender, EventArgs e)
{
dgvRequests.DataSource = GetYearData(--CurrentYear); //Or Your variable
dgvRequests.DataBind();
}
That should allow you to "Page" in essence by using controls instead of the paging feature.
** The GetYearData function is your function in which you grab your data from
** You may also want to display the current year of data your are displaying
I have developed a website in ASP.NET that can add articles into a another table that shows a product.
I have a table that displays items in a warehouse and a table showing the materials required to produce a certain product. Using a drop down list you can see which products are manufactured. When the user wants to add to the article, he pushes a button. But after the page loaded on my dropdown list shows the lowest value again instead of keeping its value. Visit the site, change the product (produkt in swedish) from "Cykel" (bicycle) to "car" and add any article and you will understand the problem. Can I do something with page load to find a solution?
Maybe I should mention that I use a datasource that I'm binding the dropdown with.
If you are binding your dropdown in pageload bind it in !ispostback..
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//Bind your dropdown
}
}
in onChange of drop down call a function, Assume that is storeValue() function and do somthing like this, [you can add attribute to dropdown as onchange="storeValue(this.value);"]
function storeValue(val)
{
localStorage.setItem("dropdownvalue",val);
}
and
var val="";
$(document).ready(function(){
val=localStorage.getItem("dropdownvalue");
//assign your value to dropdown list from here...
});
With help from the gentlemen above I find out to solve the problem. I used function that is called every time the dropdownlist index is changed. The function save the index in a session.
if (!Page.IsPostBack)
{
try
{
string test = (string)Session["test"];
int value = int.Parse(test);
DropDownList2.SelectedIndex = value;
}
catch
{
}
}
protected void DropDownList2_SelectedIndexChanged(object sender, EventArgs e)
{
Session["test"] = ""+ DropDownList2.SelectedIndex;
}
I am trying to use two DropDownLists to filter data. I set both of the OnSelectedIndexChanged Equal to the method below. The problem is it is only grabbing the SelectedIndex of the DDL that is changed. Example: if i choose a option in DDL1 it grabs that value and doesnt grab the value of DDL2. They both have the same OnSelectedIndexChanged i figured it would grab the current value of both. Is there a way to make it look at both DDL Controls?
protected void BrandsList_SelectedIndexChanged(object sender, EventArgs e)
{
int DDLcatId = CategoriesList.SelectedIndex;
int DDLBraId = BrandsList.SelectedIndex;
IQueryable<Product> DDLprodResult = GetProductsDDL(DDLcatId, DDLBraId);
if(DDLprodResult == null)
{
}
else
{
CatLab.Text = DDLprodResult.ToList().Count().ToString();
productList.DataSource = DDLprodResult.ToList();
productList.DataBind();
}
}
Your code should work. Of course only one can be changed if you have set AutoPostBack="true"(default is false) on both. But you should get the correct SelectedIndex anyway in the handler.
So i will guess: you are databinding the DropDownLists on every postback. Do this only if(!IsPostBack), otherwise you always overwrite changes with the original values.
So for example in Page_Load:
protected void Page_Load(Object sender, EvengtArgs e)
{
if(!IsPostBack)
{
// DataBind your DropDownLists
}
}
On the last page if If i have 1 or 2 items the header and the pager stretch too much.. it all autosizes..
My gridview height is not set, But I set the row property to 30pixels..still doesnt prevent the autosizing..
I was searching for a solution over the net..and the closest solution that i found was that:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if(this.GridView1.Rows.Count<this.GridView1.PageSize)//I need here to grab the last page..// do something like e.Row.... and last page.
{
foreach (GridViewRow tt in GridView1.Rows)
{ tt.Height = Unit.Pixel(30); }
}
}
It isnt correct.... what i need to happen, is when the user clicks the last page the height should be modified to to 30 pixels.
Any other ideas on how to prevent autosizing on the last page are welcome!!
To find out if you're on the last page of a paged grid and then change row heights, use the following (tested) code:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (GridView1.PageIndex == GridView1.PageCount - 1)
{
e.Row.Height = Unit.Pixel(30);
}
}
I have a simple admin panel with a simple gridview that list all articles present in the database.
I've added a filtering doodle (a textbox + a button) that allows the user to filter the gridview by a article name.
The code for the filter:
protected void ButtonSearchArticle_Click(object sender, EventArgs e)
{
{
LinqDataSourceAdminArticles.Where = "Title.Contains(" + "\"" + TextBoxSearchArticle.Text + "\")";
LinqDataSourceAdminArticles.DataBind();
}
LinqDataSourceAdminArticles.DataBind();
}
The gridview has the default quick editing and deleting enabled on it. The problem is, after I filter it with that code, it starts to select wrong rows when I click the "edit" button. Any ideas how to solve this? I know it has something to do with a postback.
I've checked Why is My GridView FooterRow Referencing the Wrong Row? and Sorted gridview selects wrong row but those didn't solve my problem.
Thanks!
When you change the GridView's Select query in your button click, it only take effects for that request. because GridView's edit command causes a postback, and in the postback the Gridview works with visible index of the edited row but without the filtering.
the best thing to do is to remove your ButtonSearchArticle_Click code and put it into your Page_Load code like this
if (TextBoxSearchArticle.Text != ""){
LinqDataSourceAdminArticles.Where = "Title.Contains(" + "\"" + TextBoxSearchArticle.Text + "\")";
LinqDataSourceAdminArticles.DataBind();
LinqDataSourceAdminArticles.DataBind();}
//Your Page Load Event
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Session["s_event"] = "0"; // Initialize session variable
BindData(); // Gridview Binding
}
}
protected void BindData()
{
if ((Session["s_event"].ToString())=="1")
{
cmdstr_ = (Session["search_item"].ToString());
}
else
{
cmdstr_ = ""; // Your command string to populate gridview
}
// `enter code here`
}
protected void btnSearch_Click(object sender, EventArgs e)
{
Session["s_event"] = 1; // Search Event becomes 1.
// Your Search Logic here
Session["search_item"] = cmdstr;
// Bind Gridview here
}