I am trying to fetch data from certain GridView row when I click link in that row...
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataSourceID="AccessDataSource1" AllowPaging="True">
<Columns>
<asp:BoundField DataField="nazivTeme" HeaderText="nazivTeme"
SortExpression="nazivTeme" />
<asp:BoundField DataField="datum" HeaderText="datum" SortExpression="datum" />
<asp:TemplateField HeaderText="View">
<ItemTemplate>
<asp:LinkButton runat="server" ID="lnkView" commandname="view"
OnClick="lnkView_Click">Komentiraj</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
I would like to get data from the row where I click the LinkButton (only first cell).
I hope you understand what I want :)
Do not subscribe to Click event of the button. Instead, subscribe to the RowCommand event of the grid view. Then, in the event handler, you can evaluate which command was received and which row was affected. Once you get the row, you can get its cell value by cell index or ID:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "view")
{
// Retrieve the row index
int index = Convert.ToInt32(e.CommandArgument);
// Retrieve the row by its index
GridViewRow row = this.GridView1.Rows[index];
// Get the 1st cell value from the row
string cellValue = r.Cells[0].Text;
}
}
Related
I'm new to ASP.NET and I am using GridView to display data on a web page. I also added a button in Gridview called process orders.
<asp:GridView ID="GridView1" runat="server" autogenerateselectbutton="True" GridLines="None" AllowPaging ="true"
OnRowCommand="GridView1_RowCommand" OnSelectedIndexChanged="GridView1_SelectedIndexChanged"
>
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="Process" runat="server"
CommandName="processorders"
CommandArgument="<%# ((GridViewRow) Container).RowIndex %>"
Text="Process orders" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
I used the row command method to get the selected index of the row.
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "processorders")
{
// Retrieve the row index stored in the
// CommandArgument property.
int index = Convert.ToInt32(e.CommandArgument);
}
Also I've implemented selectedIndexChanged method for the default select button:
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
GridViewRow row = GridView1.SelectedRow;
txtbox.Text = "You selected " + row.Cells[3].Text + ".";
}
If I try to use the GridViewRow in GridView1_RowCommand I get a null pointer exception. The row is always null but it works fine in GridView1_SelectedIndexChanged.
What am I trying to achieve is, get the column value from the selected row using my Process button and then use that value to update a database. I don't want to do it using Select.
And is there any way I can use row.Cells[] without specifying the index. I want to get the value of a column name.
Help? Please ??
I have a grid view with a list of data and a LinkButton to delete the row.
<asp:GridView ID="gridApartment" EmptyDataText="No Records Found" runat="server" AutoGenerateColumns="False" BorderWidth="0"
AllowPaging="true" ShowFooter="false" PageSize="15" Width="100%" OnPageIndexChanging="gridApartment_PageIndexChanging"
CssClass="mGrid"
OnRowDeleting="gridApartment_RowDeleting" OnRowCommand="gridApartment_RowCommand">
<AlternatingRowStyle CssClass="alt" />
<PagerStyle CssClass="pgr" />
<Columns>
<asp:TemplateField HeaderText="Building">
<ItemTemplate>
<asp:Label ID="BuildingName" runat="server" Text='<%#Eval("BuildingName") %>'></asp:Label>
</ItemTemplate>
<HeaderStyle Width="25%"></HeaderStyle>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lnkDelete" CssClass="aDelete" ToolTip="Delete" runat="server" CommandName="delete" OnClientClick=' javascript:return confirm("Are you sure you want to delete?"); '
CommandArgument='<%# Eval("RoomDetailsId") %>'>Delete</asp:LinkButton>
</ItemTemplate>
<HeaderStyle Width="8%"></HeaderStyle>
</asp:TemplateField>
</Columns>
</asp:GridView>
onload data filled by this code
gridApartment.DataSource = masterManager.GetAllRooms();
gridApartment.DataBind();
now i have a search box, and when i search, the filters result will get bind by this code.
gridApartment.DataSource = conobj.GetSearchDetails("usp_RoomDetailsSearch", "#SearchName", txtSearchterm.Text.Trim());
gridApartment.DataBind();
for delete the code is
protected void gridApartment_RowCommand(object sender, System.Web.UI.WebControls.GridViewCommandEventArgs e)
{
if (e.CommandName == "delete")
{
var masterManager = new MasterEntryManager();
int res = masterManager.DeletRoom(e.CommandArgument.ToString());
Search();
}
}
when the first time the grid get loaded e.CommandArgument has the right ID and i can delete the right row. But when i search and re bind the gridview, the e.CommandArgument value is not updated with new ID. It still return the same ID which is loaded first on page load.
For eg:
when the grid is first loaded, when i try delete the first row, e.CommandArgument has an ID say, 1001 and I deleted the record with ID 1001.
Now I load the gridview second time. Now the 1st row linkbutton e.CommandArgument has ID 1500.
I perform a search and the result grid has only 5 rows
Now i try to delete the first row, the expected linkbutton e.CommandArgument ID is say 2001, but i get the linkbutton e.CommandArgument ID as 1500, the value of first row ID when the gridview first loaded
Id is not get updated.
How can I get the updated e.CommandArgument value.?
Counter to expectations, the CommandArgument is not associated with the control that does the post back. Rather, the DataSource is returned as part of the ViewState, and the CommandArgument is referenced by the index of the control. If either the GridView or DataSource change, the index will no longer be correct.
You need to make sure that the GridView and DataSource are not updated prior referencing the CommandArgument, but then updated after the delete (it looks like you have this part). Remember that the post back event occurs after the page load.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
gridApartment.DataSource = masterManager.GetAllRooms();
gridApartment.DataBind();
}
}
I have a fairly simple GridView. This is the markup for Columns:
<Columns>
<asp:TemplateField HeaderText="JD Name" SortExpression="FullName"
HeaderStyle-HorizontalAlign="Center" ItemStyle-Width="180px" >
<ItemTemplate>
<asp:LinkButton CommandName="edt" CommandArgument='<%#Eval("JurisdictionID") %>' runat="server" Text='<%#Eval("FullName") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="JD Abbreviation" ItemStyle-Width="200px" DataField="JDAbbreviation" SortExpression="JDAbbreviation"
HeaderStyle-HorizontalAlign="Center" />
<asp:TemplateField
HeaderStyle-HorizontalAlign="Center" >
<ItemTemplate>
<asp:LinkButton ID="lnkStat" CommandName="inac" CommandArgument='<%#Eval("JurisdictionID") %>'
runat="server" Text='<%#Utils.GetStatusString((bool) Eval("IsActive")) %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
However, when I click on of the columns for sorting, it first triggers a row command event and then comes to sorting event. Can anybody tell me what is the mistake I am doing? In the RowCommand argument I get the SortExpression. This is really funny for me!
Sort is a row command. Check out this MSDN GridView.RowCommand Event article for more details.
In your row command event you should add an if statement so you can determine when the row command code should execute. Use e.CommandName.
void ContactsGridView_RowCommand(Object sender, GridViewCommandEventArgs e)
{
// If multiple buttons are used in a GridView control, use the
// CommandName property to determine which button was clicked.
if(e.CommandName=="Add")
{
// Convert the row index stored in the CommandArgument
// property to an Integer.
int index = Convert.ToInt32(e.CommandArgument);
// Retrieve the row that contains the button clicked
// by the user from the Rows collection.
GridViewRow row = ContactsGridView.Rows[index];
// Create a new ListItem object for the contact in the row.
ListItem item = new ListItem();
item.Text = Server.HtmlDecode(row.Cells[2].Text) + " " +
Server.HtmlDecode(row.Cells[3].Text);
// If the contact is not already in the ListBox, add the ListItem
// object to the Items collection of the ListBox control.
if (!ContactsListBox.Items.Contains(item))
{
ContactsListBox.Items.Add(item);
}
}
}
In my Website, I currently use a grid view which generates data from 3 tables namely status, Project_glance, Application_header. SQL Query returns 4 columns but in my grid-view i only shows 3 columns. The last column returns the Status_id of the project.The following is my .aspx code:
<asp:GridView ID="grdProf" runat="server" AllowPaging="True" AutoGenerateColumns="false" OnPageIndexChanging="grdProf_PageIndexChanging">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:HyperLink ID="hlnkView" Visible="true" Text="View" runat="server" > </asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="ApplicationID" HeaderText="ApplicantionID" />
<asp:BoundField DataField="PRGLProjectTitle" HeaderText="Project Title" />
<asp:BoundField DataField="Status" HeaderText="Project Status" />
</Columns>
</asp:GridView>
If the Status_id > 15 then only view hyperlink will visible otherwise the View hyperlink text will be changed to 'Edit' and a navigate URL will add to this hyperlink and another hyperlink 'Delete' will show to allow user to delete the project detail.
Please help me to find the correct solution for this..
First, add the delete Hyperlink to your ItemTemplate.
Then, to be able to access your Status_id field, you'll want to add that to your GridView's DataKeys.
Then, you can subscribe to your GridView's RowDataBound method, grab the Hyperlinks, check the status_id, and set the Hyperlinks' visibility accordingly.
<asp:GridView DataKeyNames="status_id"
<ItemTemplate>
<asp:HyperLink ID="hlnkView" Visible="true" Text="View" runat="server" >
<asp:HyperLink ID="hlnkDelete" Visible="false" Text="Delete" runat="server" >
</asp:HyperLink>
void GridView1_RowDataBound(object sender, GridViewRowEventArgs e) {
HyperLink delHl = e.Row.Cells[0].FindControl("hlnkDelete") as HyperLink;
int statusId = (int)(sender as GridView).DataKeys[e.Row.RowIndex].Value;
delHl.Visible = statusId <= 15;
}
Like this
protected void grdProf_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
DataRowView rowView = (DataRowView)e.Row.DataItem;
// Retrieve the status value for the current row.
string status = rowView["Status"].ToString();
//Now you have the status
//get a reference to view hyperlink and hide it if that's the case
Hyperlink hlnkView = e.Row.FindControl("hlnkView") as HyperLink;
//example:
if(int.Parse(status)>15)
hlnkView .Visible=false;//you are done
}
}
As far as displaying an "edit" hyperlink, I would have an extra column next to the "view" column and hide or display this other hyperlink as necessary since in some cases you'll need one hyperlink column and in some cases you'll need two.
I have a GridView which I bind to a SqlDataReader on Page_Load. It has a column with buttons and I am trying to get the row when a button is clicked with the following code:
int index = Convert.ToInt32(e.CommandArgument);
GridViewRow row = GridView1.Rows[index];
EDIT : Pasting the .aspx page from the comments sectio
<asp:GridView ID="GridView1" runat="server" CellPadding="4" ForeColor="#333333" OnRowCommand="GridView1_RowCommand" DataKeyNames="id" GridLines="None"> <AlternatingRowStyle BackColor="White" />
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btnChange" runat="server" Text="Change" CommandName="Test" Visible='<%# Convert.ToBoolean(Eval("Tested")) == true ? true : false %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</aspx:GridView>
I get the following error: 'System.FormatException: Input string was not in a correct format.' on line 'int index = Convert.ToInt32(e.CommandArgument);'.
Any ideas?
You need to check which command in the GridView row has been clicked. Your markup should correspondingly map. See egs below.
The e.CommandArgument you are getting may not correspond to your button click.
In CodeBehind:
void GridView1_RowCommand(Object sender, GridViewCommandEventArgs e)
{
// If multiple buttons are used in a GridView control, use the CommandName property to determine which button was clicked.
if(e.CommandName=="Add")
{
// Convert the row index stored in the CommandArgument property to an Integer.
int index = Convert.ToInt32(e.CommandArgument);
// Retrieve the row that contains the button clicked by the user from the Rows collection.
GridViewRow row = CustomersGridView.Rows[index];
// additional logic...
}
// additional logic...
}
In Markup:
Also please ensure you have set your CommandArgument attribute appropriately. Example below:
<asp:Button (...) CommandArgument="<%# Container.DataItemIndex %>" />
OR use a buttonfield
<asp:ButtonField ButtonType="button" CommandName="Add" Text="Add" />
Can u post the whole markup code,it would be helpful to solve. according to your question
in gridview aspx code you have to use Command Name, and command Argument for the Button Control and it should bind to the one of the column of db. and use Row Command event of gridview. And also Try to use ItemTemplate to put Control Inside the gridview.
Click here for MSDN Documentation. Row Command in GridView
protected void Grid_RowCommand( object sender, GridViewCommandEventArgs e )
{
int index = Convert.ToInt32( e.CommandArgument );
your logic .......
}
You have not added value to the command Argument. For your Button event in .aspx page
<asp:Button ID="btnChange" runat="server" Text="Change" CommandName="Test" CommandArgument = 1 Visible='<%# Convert.ToBoolean(Eval("Tested")) == true ? true : false %>' />
In the code behind i.e the RowCommand Event
if(e.CommandName == "Test")
{
int index = Convert.ToInt32(e.CommandArgument);
}
This will work only for value 1. To make it generic you can bind the command Argument to the value you want using one of the binding techniques for example : CommandArgument ='<%# Eval("ID") %>' (Assuming ID is present in the GridView)
Check out this code
void ContactsGridView_RowCommand(Object sender,GridViewCommandEventArgs e)
{
// If multiple buttons are used in a GridView control, use the
// CommandName property to determine which button was clicked.
if(e.CommandName=="Add")
{
// Convert the row index stored in the CommandArgument
// property to an Integer.
int index = Convert.ToInt32(e.CommandArgument);
// Retrieve the row that contains the button clicked
// by the user from the Rows collection.
GridViewRow row = ContactsGridView.Rows[index];
// Create a new ListItem object for the contact in the row.
ListItem item = new ListItem();
item.Text = Server.HtmlDecode(row.Cells[2].Text) + " " +
Server.HtmlDecode(row.Cells[3].Text);
// If the contact is not already in the ListBox, add the ListItem
// object to the Items collection of the ListBox control.
if (!ContactsListBox.Items.Contains(item))
{
ContactsListBox.Items.Add(item);
}
}
}
Below html code for gridview
<asp:gridview id="ContactsGridView"
datasourceid="ContactsSource"
allowpaging="true"
autogeneratecolumns="false"
onrowcommand="ContactsGridView_RowCommand"
runat="server">
<columns>
<asp:buttonfield buttontype="Link"
commandname="Add"
text="Add"/>
<asp:boundfield datafield="ContactID"
headertext="Contact ID"/>
<asp:boundfield datafield="FirstName"
headertext="First Name"/>
<asp:boundfield datafield="LastName"
headertext="Last Name"/>
</columns>
</asp:gridview>
Check link Gridview commands
Hope this answer helps you.