I have a grid view will two different button columns. I want to perform a different action depending on what button the user presses. How in the SelectedIndexChanged event do I determine what column was pressed. This is the code I use to generate the columns.
grdAttachments.Columns.Clear();
ButtonField bfSelect = new ButtonField();
bfSelect.HeaderText = "View";
bfSelect.ButtonType = ButtonType.Link;
bfSelect.CommandName = "Select";
bfSelect.Text = "View";
ButtonField bfLink = new ButtonField();
bfLink.HeaderText = "Link/Unlink";
bfLink.ButtonType = ButtonType.Link;
bfLink.CommandName = "Select";
bfLink.Text = "Link";
grdAttachments.Columns.Add(bfSelect);
grdAttachments.Columns.Add(bfLink);
I think it would help if you give the buttons different CommandName properties.
Here is an MSDN example of reading CommandName in the GridView_RowCommand event, which specifically mentions your multiple-button situation:
void CustomersGridView_RowCommand(Object sender, GridViewCommandEventArgs e)
{
// If multiple ButtonField column fields are used, use the
// CommandName property to determine which button was clicked.
if(e.CommandName=="Select")
{
// Convert the row index stored in the CommandArgument
// property to an Integer.
int index = Convert.ToInt32(e.CommandArgument);
// Get the last name of the selected author from the appropriate
// cell in the GridView control.
GridViewRow selectedRow = CustomersGridView.Rows[index];
TableCell contactName = selectedRow.Cells[1];
string contact = contactName.Text;
// Display the selected author.
Message.Text = "You selected " + contact + ".";
}
}
string commandName = e.CommandName.ToString().Trim();
GridViewRow row = GridView1.Rows[Convert.ToInt32(e.CommandArgument)];
switch (commandName)
{
case "showName":
LClickName.Text = "You Clicked Show Name Button : \"" + row.Cells[1].Text + "\"";
break;
case "EditName":
LClickName.Text = "You Clicked Edit Name Button : \"" + row.Cells[1].Text + "\"";
break;
default: break;
}
Here is a sample for Multiple select Button in One Gridview
Multiple Select Button In One Gridview
Related
The asp:GridView displays the order lines. It contains only two BoundFields: ID (not visible) and html_text_info (visible). The gvOrderLines.DataSource is explicitly assigned by the DataTable that was obtained by calling the SQL stored procedure. Before that,the html_text_info is added to the DataTable, and it is filled by the formatted HTML text where other columns are the source for the information. See the following method (simplified):
private void LoadGridViewOrderLines()
{
// Get the data table with the order-line data for the order.
DataTable dt = DbUtil.GetAppTable(
"usp_order_lines #order_code=#order_code",
new Hashtable { { "order_code", OrderCode } },
commandTimeoutSeconds: 180);
// Add the field html_text_info, and format the info into it.
dt.Columns.Add("html_text_info", typeof(string));
StringBuilder sb = new StringBuilder();
foreach (DataRow row in dt.Rows)
{
sb.Clear();
// Get the values from the row.
string product_code = row.Field<string>("product_code");
string product_name = row.Field<string>("product_name");
double quantity = ... get the quantity and convert to double...;
string unit = row.Field<string>("unit");
double price = ... get the price and convert to double...;
// Format it as an HTML string.
sb.Append($"{product_code}<br />");
sb.Append($"<b>{product_name}</b><br />");
sb.Append($"Quantity: <b>{quantity:f2} {unit}</b><br />");
sb.Append($"Price: <b>{price:f3}</b><br />");
// Set the formatted value to the field.
row["html_text_info"] = sb.ToString();
}
gvOrderLines.DataSource = dt;
gvOrderLines.DataBind();
}
Now, I want to edit/update the order item. So, I need to access the row from the DataTable that is used as the DataSource. I already have the handler that gets correctly the ID into the property UpdateID (because it was named as DataKeyNames="ID" for the grid view; see below). How can I get the source values that form the composed field?
protected void gvOrderLines_RowEditing(object sender, System.Web.UI.WebControls.GridViewEditEventArgs e)
{
UpdateID = (int)gvOrderLines.DataKeys[e.NewEditIndex].Value;
// How to get the source values that form the composed field?
tbCode.Text = ???;
tbName.Text = ???;
tbQuantity.Text = ???;
tbPrice.Text = ???;
gvOrderLines.EditIndex = -1; // cancel
gvOrderLines.DataBind();
}
Is the DataRow for current e.NewEditIndex easily accessible? Or do I have to search on my own in the DataTable (that is the gvOrderLines.DataSource)?
The "data row" source ONLY persists during the data binding operations.
So for example, you have "looping" code after you pull the data to on the fly create those extra columns. I often do that, but I still in most cases would suggest you do that "one row" operation in the gv, and not against the table.
This suggestion is not a "must" do, but it can help. Since then you are free to have other buttons, filters or whatever and JUST toss/pass/send/throw to the gv the data source. (so, each time you pull/create/have/use/filter etc. the data source, you don't have to modify it with that extra column.
Thus this:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRowView gData = e.Row.DataItem as DataRowView; // the data source row!!!!
Label Info = (Label)e.Row.FindControl("lblInfo");
StringBuilder sb = new StringBuilder();
sb.Clear();
// Get the values from the row.
string product_code = gData["product_code"].ToString();
string product_name = gData["product_name"].ToString();
double quantity = ... get the quantity and convert to double...;
string unit = gData["unit"].ToString();
double price = ... get the price and convert to double...;
// Format it as an HTML string.
sb.Append($"{product_code}<br />");
sb.Append($"<b>{product_name}</b><br />");
sb.Append($"Quantity: <b>{quantity:f2} {unit}</b><br />");
sb.Append($"Price: <b>{price:f3}</b><br />");
// Set the formatted value to the field.
Info.Text = sb.ToString();
}
}
however, as I stated/noted, the so-called data source (dataitem) that seems to show all over the place in most GV events, is ONLY persisted during the binding process. Once binding is done, then that data item goes out of scope.
Next up, a button click to edit/get the one row.
I (now) in most cases do NOT bother with the gv event model WHEN most of the code and editing is custom code (code you the developer is writing and wanting control of what the heck is going to occur!!!).
So, just drop in a plane jane button into the grid row, and use a plane jane standard button click event.
Say, like this:
<asp:BoundField DataField="HotelName" HeaderText="Hotel Name" />
<asp:BoundField DataField="Description" HeaderText="Description" ItemStyle-Width="270" />
<asp:TemplateField HeaderText="Edit">
<ItemTemplate>
<asp:Button ID="cmdEdit" runat="server" Text="Edit"
CssClass="btn" OnClick="cmdEdit_Click" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
So, note how I do (did not) bother with using the built in gv events.
So, the button click event - a plane jane one looks like this:
protected void cmdEdit_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
GridViewRow gRow = btn.NamingContainer as GridViewRow;
int PKID = (int)GridView1.DataKeys[gRow.RowIndex]["ID"];
Debug.Print("row index click = " + gRow.RowIndex);
Debug.Print("database PK id = " + PKID);
string strSQL = "SELECT * FROM tblHotelsA WHERE ID = " + PKID;
DataRow rstData = MyRst(strSQL).Rows[0];
.. etc. etc.
From that row click, we get/use/have the database PK id, and thus have to re-pull the data. Note how we NEVER exposed/used/have the database PK id in the gv markup - (for reasons of security). (and I see you ALSO using datakeys - good!!).
So, your edit button click (now a plane jane click event) becomes somthing like this:
protected void cmdEdit_Click(object sender, EventArgs e)
{
GridViewRow gRow = btn.NamingContainer as GridViewRow;
int PKID = (int)GridView1.DataKeys[gRow.RowIndex]["ID"];
// How to get the source values that form the composed field?
// answer: we re-pull the database row based on pk
int UpdateID = (int)gvOrderLines.DataKeys[e.NewEditIndex].Value;
string strSQL = "SELECT * FROM MyTable WHERE ID = " + UpdateID;
DataRow OneRow = MyRst(strSQL).Rows[0];
// any display value in gv - you use find control ,or cells[] collection
TextBox txtHotelName = gRow.FindControl("txtHotel") as TextBox;
Just remember that dataitem" is available ONLY during binding, and after the databinding to the gv is done, then it (the dataitem) goes out of scope.
If the value(s) you need are not in the gv "display", then you need to re-pull that one row for such values.
templated controls in gv - use find control
built in, use cells[] collection.
Now, to be fair, I don't much use the built in "edit" function, and I just drop in a simple edit button, and either hide the gv, show the hidden edit "div" I have. Or better yet, pop that div like this:
I have a grid view name gvwsponsoor and it has 8 cells every cells has template textbox. if i am double click this textbox then open a model popup. i selected this popup data the data is show the textbox. but second rows are not show data, always data show first rows, how to pass all rows show data, please tell me solution any person .
i try to solved this code but not work in this code.
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
//foreach (GridViewRow grid in gvwSponsor.Rows)
//{
TextBox CostId = (TextBox)gvwSponsor.Rows[0].Cells[2].FindControl("txtCostCenter");
TextBox CostName = (TextBox)gvwSponsor.Rows[0].Cells[1].FindControl("txtDescription");
CostId = (TextBox)gvwSponsor.Rows[0].Cells[2].FindControl("txtCostCenter");
CostName = (TextBox)gvwSponsor.Rows[0].Cells[1].FindControl("txtDescription");
CostId.Text = GridView1.SelectedRow.Cells[2].Text;
CostName.Text = GridView1.SelectedRow.Cells[1].Text;
GridView1.SelectedIndex = -1;
DataTable dtaa = new DataTable();
dtaa = bll.GetNumber(CostId.Text);
if (dtaa.Rows.Count > 0)
{
GridView2.DataSource = dtaa;
GridView2.DataBind();
}
TextBox TxtOp = (TextBox)gvwSponsor.Rows[0].FindControl("txtOP");
TxtOp.Focus();
//}
}
You should process SelectedIndexChanged function of your gridview by using gvwSponsor.SelectedRow, not gvwSponsor.Rows[0]
I Have Two Gridview in first one there is some data with checkbox. I Want when i check two or more checkboxes then show the both record who's checked to another gridview There is my Coding. Problem is it's show only one record at a time..
protected void CheckBox1_CheckedChanged(object sender, EventArgs e)
{
foreach(GridViewRow row in GridView1.Rows)
{
if (row.RowType == DataControlRowType.DataRow )
{
CheckBox chkSelect = (CheckBox)row.Cells[0].FindControl("CheckBox1");
if (chkSelect != null)
{
if (chkSelect.Checked)
{
string FoodItem = ((Label)row.FindControl("Label1")).Text.ToString();
string s = "select * from Item where Item_Name='" + FoodItem + "' ";
db.grid(s, GridView2);
}
}
}
}
By looking your code,
first think dont bind gridview immediately after checking checked property of each check box, it will override gridview2. first collect all check box values by concatinating say FoodItem = "(value1,value2,value3)".
call data base one time by modifying query like
string s = "select * from Item where Item_Name in " + FoodItem +";
db.grid(s, GridView2);
I think you have multiple selection so keep seperate button and write all codes to copy from one grid to another grid inside button click event.
I am using a Grid View on my page.
I want to show the data of the selected row cell through response.write(), on the click event of the page button.
Note::
please set the CommandName of your
button to "selectCol"
Please set the CommandName for the
second button , you will use to
delete
to"deleteCol"
Set the command argument property for your button :
.aspx
CommandArgument='<%#((GridViewRow)Container).RowIndex%>'
CommandArgument='<%#((GridViewRow)Container).RowIndex%>'
for the two buttons.
.cs
protected void gv_RowCommand(object sender, GridViewCommandEventArgs e)
{
try
{
int index = Convert.ToInt32(e.CommandArgument);
if (e.CommandName == "selectCol")
{
Response.Write(gv.Rows[index].Cells[0].Text); //consider you use bound field and the column you want to show its value is the first column.
}
else if(e.CommandName == "deleteCol")
{
int id = int.Parse(gv.DataKeys[index].Value.ToString());//the primary key for your table.
Delete(id);//method which use (Delete From .... Where id = ....).
}
gv.DataBind();
}
catch (Exception ee)
{
string message = ee.Message;
}
}
Greeting Hims.
Easyest way to read value from gridview field is to write:
your_grid_name.SelectedRow.Cell(*number_of_index*).text
In my case that is:
Dim employer_name As String
employer_name=poslodavac_grid.SelectedRow.Cells(1).Text
Just remember that first cell index is zero and that doesn't count "asp:CommandField ShowSelectButton" tag as first one ...
Use GridView.SelectedRow property.
String cellText = this.gridView.SelectedRow.Cells[cellIndex].Text;
Refer to the following to learn about selecting a row in a GridView control.
Select Command in a GridView Control in ASP.Net
If you are using a LINK BUTTON in your grid view, you can use the following code in the ROWCOMMAND method. This code with retrieve all the values in the particular selected row.
// to get the value of the link use the command argument
FaultId = Convert.ToInt32(e.CommandArgument);
// to get the other column values
UserId = Convert.ToInt32(((GridViewRow(((LinkButton)e.CommandSource).NamingContainer)).Cells[1].Text);
Department = ((GridViewRow(((LinkButton)e.CommandSource).NamingContainer)).Cells[2].Text;
ProblemType = ((GridViewRow)(((LinkButton)e.CommandSource).NamingContainer)).Cells[3].Text;
You can get it in the RowCommand event of the gridview:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Select")
{
GridViewRow row = (GridViewRow)(((Button)e.CommandSource).NamingContainer);
Response.Write(row.Cells[0].Text);
Response.Write(row.Cells[1].Text);
................
}
}
i tried something like this but did not work:
GridViewRow row = (GridViewRow)(((Repeater)e.CommandSource).NamingContainer);
Repeater _rpt1 = row.Cells[8].FindControl("rptReg") as Repeater;
error:
Unable to cast object of type 'System.Web.UI.WebControls.Button' to type 'System.Web.UI.WebControls.Repeater'.
is there a way i can have the below code in OnRowCommand event using GridView?
actually i am trying to delete the row from the gridview control and when the user click on it and i am grabbing the mulitple ids and passing to SP and update the table and databind the gridview
GridViewRow row = gv.SelectedRow;
Repeater _rpt = gv.Rows[e.RowIndex].Cells[8].FindControl("rptReg") as Repeater;
Repeater _rpt1 = gv.Rows[e.RowIndex].Cells[9].FindControl("rptVisitor") as Repeater;
foreach (RepeaterItem item in _rpt.Items)
{
TextBox _txt = item.FindControl("txtId") as TextBox;
TextBox _txt1 = item.FindControl("txtName") as TextBox;
//update db
}
Please try this:
var viewRow = (GridViewRow)(((ImageButton)e.CommandSource).NamingContainer);
foreach (GridViewRow gvr in gvDetails.Rows)
{
var btnSelect = (ImageButton)viewRow.FindControl("btnSelect");
if (gvr == viewRow)
{
if (btnSelect.ImageUrl.ToLower() == "~/images/rbnormal.jpg")
{
btnSelect.ImageUrl = "~/Images/rbSelected.jpg";
btnSelect.Enabled = false;
}
}
else
{
btnSelect.ImageUrl = "~/Images/rbnormal.jpg";
btnSelect.Enabled = true;
}
}
Your error is telling me that the control named "rptReg" is a button.
The GridView has a property called DataKeys which can hold multiple IDs
So you would pull out the "PersonId" like:
string personId = GridView1.DataKeys[e.RowIndex]["PersonId"].ToString();