Getting the index of the last row inserted in a GridView - asp.net

How do I get the row index of the last row inserted in a GridView considering the user may have custom ordering in the grid (I can't use the last row).
protected void ButtonAdd_Click(object sender, EventArgs e)
{
SqlDataSourceCompleteWidget.Insert();
GridViewCompleteWidget.DataBind();
GridViewCompleteWidget.EditIndex = ??????;
}
I want to put the row into edit mode immediately after the insert occurs.
UPDATE
protected void ButtonAdd_Click(object sender, EventArgs e)
{
//SqlDataSourceCompleteWidget.InsertParameters.Add("EFFECTIVE_DATE", Calendar1.SelectedDate.ToString("yyyy-MM-dd"));
SqlDataSourceCompleteWidget.InsertParameters[0].DefaultValue = Calendar1.SelectedDate.ToString("yyyy-MM-dd");
SqlDataSourceCompleteWidget.Insert();
GridViewCompleteWidget.DataBind();
GridViewCompleteWidget.EditIndex = 1;
}
private int mostRecentRowIndex = -1;
protected void GridViewCompleteWidget_RowCreated(object sender, GridViewRowEventArgs e)
{
mostRecentRowIndex = e.Row.RowIndex;
//GridViewCompleteWidget.EditIndex = e.Row.RowIndex;
}

You would want to handle the RowCreated event. You can access the row data and identity/location using the GridViewRowEventArgs object that is passed to this event handler.
void YourGridView_RowCreated(Object sender, GridViewRowEventArgs e)
{
YourGridView.EditIndex = e.Row.RowIndex;
}

Edit using the gridview's onitemcommand. Then you can use a binding expression on the grid column to set whatever you want. If you are using a button or linkbutton or several others you could use the CommandArgument
CommandArgument='<%# Eval("DataPropertyIWant") %>'

Edit
Sorry I skipped that ordering was done by user. I've tested the following code and it works having respected the users ordering of items, but we must take the user to the page where the last row exists.
1st: Retrieve the Max(ID) from database after insertion, store it in a session
select Max(ID) from tbl_name; -- this statement can retrieve the last ID
Session["lastID"]=lastID;
2nd:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType==DataControlRowType.DataRow)
if (Session["lastID"] != null)
if ((int)DataBinder.Eval(e.Row.DataItem, "ID") == (int)Session["lastID"])
{
//Session["rowIndex"] = e.Row.RowIndex;
int rowIndex=e.Row.RowIndex;
if (Session["type"] != null)
if (Session["type"].ToString() == "Normal")
{
int integ;
decimal fract;
integ = rowIndex / GridView1.PageSize;
fract = ((rowIndex / GridView1.PageSize) - integ;
if (fract > 0)
GridView1.PageIndex = integ;
else if (integ > 0) GridView1.PageIndex = integ - 1;
GridView1.EditIndex = rowIndex;
}
}
}
3rd: Convert your commandField into TemplateFields and Set their CommandArgument="Command"
I'll use this argument to identify what triggered RowDataBound event. I store the value in a Session["type"]. The default value is "Normal" defined in the page load event.
if(!IsPostBack)
Session["type"]="Normal";
the other value is set in RowCommand event
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandArgument == "Command")
Session["type"] = "Command";
}
It works for me fine.
Sorry for my language and,may be, unnecessary details.

UPDATE: I worked off of this post
I'm assuming you just return a value after doing the insert but you can set ID wherever you insert the record.
private int mostRecentRowIndex = -1; //edit index
private bool GridRebound = false; //used to make sure we don't rebind
private string ID; //Is set to the last inserted ID
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
//Set so grid isn't rebound on postback
GridRebound = true;
}
}
protected void ButtonAdd_Click(object sender, EventArgs e)
{
SqlDataSourceCompleteWidget.InsertParameters[0].DefaultValue = Calendar1.SelectedDate.ToString("yyyy-MM-dd");
ID = SqlDataSourceCompleteWidget.Insert();
GridViewCompleteWidget.DataBind();
}
protected void GridViewCompleteWidget_RowDataBound(object sender, GridViewRowEventArgs e)
{
//Check that the row index >= 0 so it is a valid row with a datakey and compare
//the datakey to ID value
if (e.Row.RowIndex >= 0 && GridViewCompleteWidget.DataKeys[e.Row.RowIndex].Value.ToString() == ID)
{
//Set the edit index
mostRecentRowIndex = e.Row.RowIndex;
}
}
protected void GridViewCompleteWidget_DataBound(object sender, EventArgs e)
{
//Set Gridview edit index if isn't -1 and page is not a post back
if (!GridRebound && mostRecentRowIndex >= 0)
{
//Setting GridRebound ensures this only happens once
GridRebound = true;
GridViewCompleteWidget.EditIndex = mostRecentRowIndex;
GridViewCompleteWidget.DataBind();
}
}
Selects if inserting last record in gridview (no sorting)
You should be able to get the number of rows from the datasource: (minus 1 because the rows start at 0 and the count starts at 1)
GridViewCompleteWidget.EditIndex = ((DataTable)GridViewCompleteWidget.DataSource).Rows.Count - 1;
But put this before you bind the data:
protected void ButtonAdd_Click(object sender, EventArgs e)
{
SqlDataSourceCompleteWidget.Insert();
GridViewCompleteWidget.EditIndex = ((DataTable)GridViewCompleteWidget.DataSource).Rows.Count - 1;
GridViewCompleteWidget.DataBind();
}

Related

Incrementing variables in ASP.net on every button click

I want to increment date in every click ASP.NET.
But Every time the page posts back, it is essentially starting over from scratch - anything initialized to 0.
I need to persist a value across postbacks but I don't how to do that. I would appreciate for any help.
Here is what I'am trying to do:
int myNumber = 0;
protected void Button1_Click1(object sender, EventArgs e)
{
lblDate.Text = DateTime.Now.StartOfWeek(DayOfWeek.Monday).AddDays(myNumber).ToShortDateString();
myNumber++;
}
Update:
My finaly goal is to get next weeks first day with next button and Previous week, I mean I want to forword and backword...
public int NextCount
{
get { return ViewState["Count"] != null ? (int)ViewState["Count"] : 7; }
set { ViewState["Count"] = value; }
}
protected void btnNext_Click1(object sender, EventArgs e)
{
lblsum.Text = DateTime.Now.StartOfWeek(DayOfWeek.Monday).AddDays(NextCount).ToShortDateString();
NextCount = NextCount+7;
}
protected void btnPrevious_Click(object sender, EventArgs e)
{
lblsum.Text = DateTime.Now.StartOfWeek(DayOfWeek.Monday).AddDays(NextCount).ToShortDateString();
NextCount = NextCount - 7;
}
But When I click Prev button .. there is delay with one click after two or three Click then reaction coming the same with next button when you click from prev to next. Maybe I have to store it in session?
I have updated your code below by using ViewState to handle this. Other easiest option would be storing the same in Session, Cache or Cookie.
While storing a value in ViewState, it will create a hidden field
in the page and store the value to maintain it across the postback.
public int NextCount
{
get { return ViewState["NextCount"] != null ? (int)ViewState["NextCount"] : 0; }
set { ViewState["NextCount"] = value; }
}
protected void btnNext_Click1(object sender, EventArgs e)
{
NextCount = NextCount+7;
lblsum.Text = DateTime.Now.StartOfWeek(DayOfWeek.Monday).AddDays(NextCount).ToShortDateString();
}
protected void btnPrevious_Click(object sender, EventArgs e)
{
NextCount = NextCount - 7;
lblsum.Text = DateTime.Now.StartOfWeek(DayOfWeek.Monday).AddDays(NextCount).ToShortDateString();
}

How to remove row from gridview on row command event?

I am trying to remove row from gridview by click on ImageButton which is placed inside gridview. I am getting row index but dont know how to remove. My gridview binds from session and i dont want to rebind gridview.
Here is my code:
protected void GVDetail_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName.Equals("Remove"))
{
List<Class1> list = (List<Class1>)Session["value1"];
int index = Convert.ToInt32(e.CommandArgument);
GridViewRow gridRow = gvDetail.Rows[index];// (GridViewRow)(((ImageButton)e.CommandSource).NamingContainer);
((List<Class1>)Session["value1"]).RemoveAt(index);
}
}
If anyone have any idea about this than please help me..
Use the gridview deleterow method.
void GVDetail_RowCommand_RowCommand(Object sender, GridViewCommandEventArgs e)
{
if(e.CommandName=="Remove")
{
var id = Int32.Parse(e.CommandArgument);
GVDetail.DeleteRow(id);
}
}
protected void GVPurchaseOrderTax_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
try
{
if (dt.Rows.Count > 0)
{
dt.Rows[e.RowIndex].Delete();
GVPurchaseOrderTax.DataSource = dt;
GVPurchaseOrderTax.DataBind();
}
}
}

gridview on select row event

How do I do a grdiview on select row event? On the source page, I added
OnSelectedIndexChanged="grdTanks_OnSelectRow"
in the code behind, I put the function
protected void grdTanks_OnSelectRow(Object sender, GridViewCommandEventArgs e)
{
}
When I try to do it that way, I get No overload for grdTanks_OnSelectRow matches delegate 'System.EventHandler'
If I change the GridViewComandEventArgs to EventArgs, then it won't allow me to do
if (e.CommandName == "Select")
anybody know how to do a OnSelectRow event for a gridview? Thanks
I also added this code:
protected void grdTanks_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if (e.Row.RowIndex != -1)
{
e.Row.Attributes["onmouseover"] = "this.style.cursor='hand';this.style.background='#3260a0';;this.style.color='white'";
if (e.Row.RowIndex % 2 == 1)
{
e.Row.Attributes["onmouseout"] = "this.style.textDecoration='none';this.style.background='white';this.style.color='black'";
}
else
{
e.Row.Attributes["onmouseout"] = "this.style.textDecoration='none';this.style.background='#bEc8bE';this.style.color='black'";
}
e.Row.Attributes["onclick"] = ClientScript.GetPostBackClientHyperlink(this.grdTanks, "Select$" + Convert.ToString(DataBinder.Eval(e.Row.DataItem, "CargoTankID")));
}
}
}
You could try this:
In the page_load, enter
grdTanks.SelectedIndexChanged +=
and press tab twice. Visual Studio automatically generates the handler for you. The second param would be EventArgs
I think you have to change
protected void grdTanks_OnSelectRow(Object sender, GridViewCommandEventArgs e)
To
protected void grdTanks_SelectedIndexChanged(Object sender, GridViewCommandEventArgs e)
In your code behind
I am not sure what you want to do in this event handler. You are already handling for select event and I think, no need to check again for (e.CommandName == "Select"). (MSDN:The SelectedIndexChanged event is raised when a row's Select button is clicked).
The error said no overload for event and you have to use EventArgs argument.
protected void grdTanks_OnSelectRow(Object sender, EventArgs e)
{
// May be you want like..
// Get the currently selected row using the SelectedRow property.
GridViewRow row = YourGridViewID.SelectedRow;
}

How do i know id of ListView item on OnItemUpdated?

I have suppliers table with id int value for each supplier. I'm trying to edit columns of this table inside of ListView.
i'm trying to access e arg but it doesn't have any data on id of the row i'm trying to update?
You need to set the ListView.DataKeyNames to contain the property name of the uniqueId
<asp:ListView runat="server" ID="LvSample" DataKeyNames="SupplierId"/>
Then the dataKey will be available in the update events. It is worth nothing that you might want to use the ItemUpdating event instead of the ItemUpdated as this happens before Update occurs.
protected void Page_Load(object sender, EventArgs e)
{
LvSample.ItemUpdating += new EventHandler<ListViewUpdateEventArgs>(LvSample_ItemUpdating);
LvSample.ItemUpdated += new EventHandler<ListViewUpdatedEventArgs>(LvSample_ItemUpdated);
}
void LvSample_ItemUpdated(object sender, ListViewUpdatedEventArgs e)
{
var supplierId = e.NewValues["SupplierId"];
}
void LvSample_ItemUpdating(object sender, ListViewUpdateEventArgs e)
{
var supplierId = e.Keys["SupplierId"];
}
use the sender instead of the e
protected void ListView1_ItemUpdated(object sender, ListViewUpdatedEventArgs e)
{
if ((sender as ListView) != null)
{
ListView l = (ListView)sender;
l.SelectedIndex;
l.etc..............
DataKey key = l.SelectedDataKey;
object k = key.Values["foo"];
}
}

asp.net making a gridView column invisible

This is a Master-Detail form. Master is a GridView. And, the Detail is a DetailsView.
The entire thing is achieved programmatically.
As you can see from the code, DetailsView is using the Master-objects's ID to retrieve the Detail items.
I need to make the ID column of the Master-GridView invisible. Coz, it is irrelevent for the user of the page. But it must not harm the page logic.
But the code-line, GridView1.Columns[1].Visible = false; is generating an exception.
Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
How should I solve this problem?
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindData();
}
}
protected void BindData()
{
List<Order> orders = Order.Get();
GridView1.DataSource = orders;
GridView1.DataBind();
// This is giving Error...............!!!
GridView1.Columns[1].Visible = false;
// At first, when the page first loads,
// GridView1.SelectedIndex == -1
// So, this is done to automatically select the 1st item.
if (GridView1.SelectedIndex < 0)
{
GridView1.SelectedIndex = 0;
}
int selRowIndex = GridView1.SelectedIndex;
int selMasterId = Convert.ToInt32(GridView1.Rows[selRowIndex].Cells[1].Text);
Order master = Order.Get(selMasterId);
labItemsCount.Text = master.Items.Count.ToString();
DetailsView1.DataSource = master.Items;
DetailsView1.DataBind();
}
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
BindData();
}
protected void DetailsView1_PageIndexChanging(object sender, DetailsViewPageEventArgs e)
{
DetailsView1.PageIndex = e.NewPageIndex;
BindData();
}
}
Have you considered using the DataKeyNames property of the gridview? This way you can remove the 'id' column from the GridView bu still access the 'id' value in the Page_Load.
DataKeyNames = "id"
Then you can get the value of the id like this.
int selRowIndex = GridView1.SelectedIndex;
int selMasterId = Convert.ToInt32(GridView.DataKeys[selRowIndex].Value);
Order master = Order.Get(selMasterId);
Alternately, you could try changing the visibility of the column in the OnRowBound event of the GridView.
protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header ||
e.Row.RowType == DataControlRowType.DataRow ||
e.Row.RowType == DataControlRowType.Footer)
{
e.Row.Cells[1].Visible = false;
}
}

Resources