I have a link button inside a gridView as below :
<asp:TemplateField HeaderText="Analyze">
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" Text="Analyze" runat="server" OnClick="LinkButton1_Click" />
</ItemTemplate>
</asp:TemplateField>
I have the LinkButton1_Click function as below :
protected void LinkButton1_Click(object sender, EventArgs e)
{
testtb.Text = name;
Console.WriteLine(name);
}
This variable "name" is the first column of the GridView.I am obtaining the value for "name" as below:
protected void UnanalysedGV_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRowView d = (DataRowView)e.Row.DataItem;
name = d["resultId"].ToString();
}
}
I want that on click of the link button the value of first column in that row of gridview becomes the text for the textbox testtb.
Somehow,the value for name remains null.
EDIT
I found out that probably RowDataBound isn't the correct event for my requirements because I need the value for each row.
So I removed the RowDataBound function.
I guess I have to handle this inside LinkButton1_Click itself.
I added this line to the function :
name = UnanalysedGV.SelectedRow.Cells[1].Text;
Still doesn't work.
Does anyone have any idea ?
You can do it using two approaches as mentioned below.
Handle click event of linkbutton through event bubbling code -
<asp:GridView AutoGenerateColumns="false" runat="server" ID="grdCustomPagging" OnRowCommand="grdCustomPagging_RowCommand">
<Columns>
<asp:BoundField DataField="RowNumber" HeaderText="RowNumber" />
<asp:BoundField DataField="DealId" HeaderText="DealID" />
<asp:BoundField DataField="Dealtitle" HeaderText="DealTitle" />
<asp:TemplateField HeaderText="View">
<ItemTemplate>
<asp:LinkButton runat="server" ID="lnkView" CommandArgument='<%#Eval("DealId") %>'
CommandName="VIEW">View Deal</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
protected void grdCustomPagging_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "VIEW")
{
LinkButton lnkView = (LinkButton)e.CommandSource;
string dealId = lnkView.CommandArgument;
}
}
Handle click event of linkbutton directly click event code -
<asp:GridView AutoGenerateColumns="false" runat="server" ID="grdCustomPagging">
<Columns>
<asp:BoundField DataField="RowNumber" HeaderText="RowNumber" />
<asp:BoundField DataField="DealId" HeaderText="DealID" />
<asp:BoundField DataField="Dealtitle" HeaderText="DealTitle" />
<asp:TemplateField HeaderText="View">
<ItemTemplate>
<asp:LinkButton runat="server" ID="lnkView" OnClick="lnkView_Click">View Deal</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
protected void lnkView_Click(object sender, EventArgs e)
{
GridViewRow grdrow = (GridViewRow)((LinkButton)sender).NamingContainer;
string rowNumber = grdrow.Cells[0].Text;
string dealId = grdrow.Cells[1].Text;
string dealTitle = grdrow.Cells[2].Text;
}
Hope this helps.
Related
I have a status column which includes approved, rejected or cancelled. I have another Actions column which contain link buttons approve and reject. Now if the status is Cancelled, I want the link button to be disabled for that row.
I tried to use GridView1_DataBound event but couldn't figure out the logic.
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if (Server.HtmlDecode(e.Row.Cells[0].Text.Trim()).Equals("Cancelled"))
{
//OR you can disable it instead of complately hiding it
((LinkButton)GridView1.Rows[e.Row.RowIndex].Cells[0].Controls[0]).Enabled = false;
}
}
}
Method A
The following should work:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:BoundField HeaderText="Status" DataField="Status" />
<asp:TemplateField HeaderText="Actions">
<ItemTemplate>
<asp:LinkButton runat="server" Enabled='<%# !(Eval("Status").ToString().Equals("Cancelled")) %>'>Approve</asp:LinkButton>
<asp:LinkButton runat="server" Enabled='<%# !(Eval("Status").ToString().Equals("Cancelled")) %>'>Reject</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Method B
Nevertheless, if you do insist on the code-behind approach the safest way to access the LinkButton controls is the following:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" OnRowDataBound="GridView1_RowDataBound">
<Columns>
<asp:BoundField HeaderText="Status" DataField="Status" />
<asp:TemplateField HeaderText="Actions">
<ItemTemplate>
<asp:LinkButton ID="ApproveButton" runat="server">Approve</asp:LinkButton>
<asp:LinkButton ID="RejectButton" runat="server">Reject</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if (e.Row.Cells[0].Text.Equals("Cancelled"))
{
((LinkButton)e.Row.FindControl("ApproveButton")).Enabled = false;
((LinkButton)e.Row.FindControl("RejectButton")).Enabled = false;
}
}
}
Explanation
Your code doesn't work because the LinkButton controls are not placed in the cell's Controls collection in the way you're expecting them to. Find out yourself by placing a breakpoint inside the inner condition of GridView1_RowDataBound and check out the items of the Controls collection. You'd be surprised!
Maybe you can use this code
<asp:GridView ID="gridView" runat="server" AutoGenerateColumns="False" OnRowDataBound="gridView_RowDataBound">
<Columns>
<asp:BoundField HeaderText="Column1" DataField="Column1" />
<asp:BoundField HeaderText="Column2" DataField="Column2" />
<asp:TemplateField HeaderText="Status">
<ItemTemplate>
<asp:Label runat="server" ID="lblStatus" Text='<%#Bind("Status") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Actions">
<ItemTemplate>
<asp:LinkButton ID="lnkAction" runat="server">Approve</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
protected void gridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var status = (e.Row.FindControl("lblStatus") as Label).Text;
if (status == "Cancelled")
{
(e.Row.FindControl("lnkAction") as LinkButton).DisableControl("Disabled button.");
}
}
}
And to disable the button you can use an extension method
public static class Extensions
{
public static TControl DisableControl<TControl>(this TControl control, string desableMessage) where TControl : WebControl
{
control.Attributes.Add("disabled", "");
control.Attributes.Add("data-toggle", "tooltip");
control.Attributes.Add("title", disableMessage);
control.Enabled = false;
return control;
}
}
I Have a GridView which conntains multiple records and couple of Link Buttons Named Edit and Detail. Now i want to Get the Name of the User (NOT Index), when a user click on Detail Link Button. Like "Name", "FatherName" etc
Here is the .aspx code
<asp:GridView ID="dgvEmployeesInformation" runat="server" CssClass=" table table-bordered table-hover table-responsive" DataKeyNames="Id" AutoGenerateColumns="False" OnRowCommand="dgvEmployeesInformation_RowCommand" OnRowDataBound="dgvEmployeesInformation_RowDataBound" AllowPaging="True" AllowSorting="True" OnPageIndexChanging="dgvEmployeesInformation_PageIndexChanging">
<%--1st Column--%>
<Columns>
<asp:BoundField HeaderText="ID" DataField="Id" ControlStyle-BackColor="#0066ff" Visible="False">
<ControlStyle BackColor="#0066FF"></ControlStyle>
</asp:BoundField>
<asp:BoundField HeaderText="Name" DataField="Name" />
<asp:BoundField HeaderText="Employee No" DataField="EmployeeNo" />
<asp:BoundField HeaderText="Father Name" DataField="FatherName" />
<asp:HyperLinkField DataNavigateUrlFields="Id" DataNavigateUrlFormatString="AddEmployeeBasic1.aspx?thid={0}" HeaderText="Update" NavigateUrl="~/AddEmployeeBasic1.aspx" Text="Edit" />
<asp:TemplateField HeaderText="Action" ShowHeader="True">
<ItemTemplate>
<asp:LinkButton ID="lbDelete" runat="server" CausesValidation="False" CommandName="Delete" Text="Delete"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton runat="server" ID="lbDetail" OnClick="lbDetail_Click" DataNavigateUrlFields="Id" DataNavigateUrlFormatString="EmployeesDetails.aspx?EmpID={0}" NavigateUrl="~/EmployeesDetails.aspx" HeaderText="Show Detail" Text="Detail"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Here is the lbDetail_Click Code
protected void lbDetail_Click(object sender, EventArgs e)
{
GridViewRow clickedRow = ((LinkButton)sender).NamingContainer as GridViewRow;
Label lblUserName = (Label)clickedRow.FindControl("Name");
EmployeeID.EmpName = lblUserName.ToString();
}
When i put my program on Debugging mode, the lblUserName return NULL
Here is the picture.
What i want is that, when a user click on Detail LinkButton, then on lbDetail Click event, it gets the Name of the Employee and store it in a static variable. Following is the picture
I don't understand how to solve this problem. Please help me through this. Your help will be really appreciated.
I would just add data attributes to the details button then get it's values at code behind.
For example:
1.) Add new data-myData='<%# Eval("Name") %>' attribute and its value to button
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton runat="server" ID="lbDetail" OnClick="lbDetail_Click" Text="Detail" data-ID='<%# Eval("ID") %>' data-myData='<%# Eval("Name") %>' ></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
2.) Get those data from event handler
protected void lbDetail_Click(object sender, EventArgs e)
{
LinkButton button = (LinkButton)sender;
var name = (string)button.Attributes["data-myData"];
var selectedID = (string)button.Attributes["data-ID"];
Session["selectedID"] = selectedID ;
}
lblUserName is null because it's not a Label, but a BoundField.
What you could do it get the Cell value.
protected void lbDetail_Click(object sender, EventArgs e)
{
GridViewRow clickedRow = ((LinkButton)sender).NamingContainer as GridViewRow;
Label1.Text = clickedRow.Cells[1].Text;
}
Or use a TemplateField that does contain a Label Name
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<asp:Label ID="Name" runat="server" Text='<%# Eval("Name")%>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
Here is how your code should look:
protected void lbDetail_Click(object sender, EventArgs e)
{
GridViewRow clickedRow = ((LinkButton)sender).NamingContainer as GridViewRow;
var username = clickedRow.Cells[1].Text;
if(string.IsNullOrEmpty(username))
{
return;
}
EmployeeID.EmpName = username;
}
Each row of the GridView is populated from a SQL DB.
Each row has a LinkButton that brings up a popup.
In the code behind I want to have access to the DataField="RCID"
I guess I'd like to attach the RCID field to the Upload link so when it's clicked I have access to the RCID within the function that handles the onclick.
How do I get this rows RCID?
<asp:GridView ID="GridView1" runat="server"
OnPageIndexChanging="GridView1_PageIndexChanging"
GridLines="Horizontal" AllowPaging="true" OnRowCommand="GridView1_RowCommand" AutoGenerateColumns="false">
<Columns>
<asp:BoundField HeaderText="RCID" DataField="RCID" Visible="false"></asp:BoundField>
<asp:BoundField HeaderText="RC Type" DataField="RCType"></asp:BoundField>
<asp:BoundField HeaderText="Channel" DataField="Channel"></asp:BoundField>
<asp:BoundField HeaderText="Total" DataField="Total"></asp:BoundField>
<asp:BoundField HeaderText="Expired In 30 Days" DataField="ExpiredIn30Days"></asp:BoundField>
<asp:BoundField HeaderText="Expired In 60 Days" DataField="ExpiredIn60Days"></asp:BoundField>
<asp:BoundField HeaderText="Expired In 90 Days" DataField="ExpiredIn90Days"></asp:BoundField>
<asp:BoundField HeaderText="Last Updated" DataField="LastUpdated"></asp:BoundField>
<asp:TemplateField HeaderText="Management">
<ItemTemplate>
<asp:LinkButton runat="server" ID="Upload" Text="Upload" CommandName="Upload" ></asp:LinkButton> |
<asp:LinkButton runat="server" ID="Details" Text="Details" CommandName="Details"></asp:LinkButton> |
<asp:LinkButton runat="server" ID="Files" Text="Files" CommandName="Files"></asp:LinkButton> |
<asp:LinkButton runat="server" ID="Edit" Text="Edit" CommandName="Edit"></asp:LinkButton> |
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Possible solution would be as follows:
Add RowCreated and RowCommand events for GridView
In RowCreated event, I have set “Visible” property to “false” for first column for both header and data row.
In RowCommand event, CommandName is checked first and then index for select command is retrieved. I have retrieved the row for that index and then retrieved the text in the specified row cell.
check this example:
protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
e.Row.Cells[0].Visible = false;
}
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Cells[0].Visible = false;
}
}
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Select")
{
int index = Convert.ToInt32(e.CommandArgument);
GridViewRow row = GridView1.Rows[index];
Label1.Text = (row.Cells[0].Text);
}
}
Second approach:
Assign command argument to your hidden field value. This will reduce another efforts. check this way:
<asp:TemplateField HeaderText="Action3" Visible="false">
<ItemStyle HorizontalAlign="Center"></ItemStyle>
<ItemTemplate>
<asp:LinkButton ID="lnkretqty" runat="server" Text="Return Qty" CommandName="RETQTY" ToolTip="Click here to Add Return Qty Entry"
CommandArgument='<%# Container.DataItemIndex %>'>
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
Code Behind code
protected void gvsearch_RowCommand(object sender, GridViewCommandEventArgs e)
{
try
{
if (e.CommandName == "SRCSELREC")
{
Int32 rowind = Convert.ToInt32(e.CommandArgument.ToString());
string val = ((Label)gvgpitemdtl.Rows[rowind].FindControl("d")).Text.ToString();
}
}
catch (Exception ex)
{
General.MessageBox(this.Page, "Error at Gridview Row Command : " + ex.Message.ToString());
return;
}
}
References:
Way of getting Hidden column value in GridView
How to Get Hidden Column values in GridView
To Find Control in GridView on RowCommand event in asp.net
How to hide GridView column and retrieve value from hidden column cell in ASP.NET
Add CommandArgument='<%# Eval("RCID") %>' in the linkbutton's markup:
<asp:LinkButton runat="server" ID="Upload" Text="Upload" CommandName="Upload" CommandArgument='<%# Eval("RCID") %>'/>
Now, in the code behind of the handler, just read the CommandArgumentproperty of the passed GridViewCommandEventArgs parameter:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Upload")
{
var valueOfRCID = e.CommandArgument;
}
}
mshsayem may be right but note you can also just grab the value from within the click event as follows
<asp:LinkButton runat="server" ID="Upload" Text="Upload" OnClick="Upload_Click" CommandArgument='<%# Eval("RCID") %>'/>
protected void Upload_Click(object sender, EventArgs e)
{
LinkButton btn = (LinkButton)(sender);
string RCID = btn.CommandArgument;
}
I have a grid view as under
<asp:GridView ID="dgTask" runat="server" Width="100%"
AutoGenerateColumns="False" onrowdatabound="dgTask_RowDataBound">
<Columns>
<asp:BoundField DataField="TaskID" HeaderText="TaskID" ItemStyle-Width="1%" />
<asp:BoundField DataField="TaskName" HeaderText="Task Name" ItemStyle-HorizontalAlign="left"
ItemStyle-Width="10%" />
<asp:BoundField DataField="PriorityName" HeaderText="Priority" ItemStyle-HorizontalAlign="center"
ItemStyle-Width="10%" />
<asp:BoundField DataField="StatusName" HeaderText="Status" ItemStyle-HorizontalAlign="center"
ItemStyle-Width="10%" />
<asp:TemplateField HeaderText="Edit Task" ItemStyle-Width="10%">
<ItemTemplate>
<asp:LinkButton ID="lnkBtnEdit" runat="Server" Text="Edit" CommandArgument ='<%# Eval("TaskID") %>' />
<asp:TextBox ID="txtId" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Now, what I have to do is that on click event of the linkButton, i need to hide the text box controls for that row.
How to do so?
So far I have done as under
protected void dgTask_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
LinkButton btnEdit = (LinkButton)e.Row.Cells[4].FindControl("lnkBtnEdit");
btnEdit.Attributes.Add("onclick", "return Test();");
}
}
Thanks
You are on the right track, just make minor changes in calling the javascript function and also add the javascript function as below.
protected void dgTask_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
LinkButton btnEdit = (LinkButton)e.Row.Cells[4].FindControl("lnkBtnEdit");
TextBox txtId = (TextBox)e.Row.Cells[4].FindControl("txtId");
btnEdit.Attributes.Add("onclick", "return Test("'" + txtId.ClientId + "'");");
}
}
And add Javascript like this way,
function Test(var txtId)
{
var inputtxt = document.getElementById(txtId);
if(inputtxt != null)
{
inputtxt.Attributes.Add("style","display:none;");
}
}
Try This :
protected void LinkButton1_Click(object sender, EventArgs e)
{
LinkButton b = (LinkButton)sender;
GridViewRow r = (GridViewRow)b.NamingContainer;
((TextBox)(GridView1.Rows[r.RowIndex].Cells[0].FindControl("TextBox1"))).Visible = false;
}
<asp:GridView ID="gvGrid" runat="server" AutoGenerateColumns="False"
DataSourceID="dsDataSource" AllowPaging="True" PageSize="20" >
<Columns>
<asp:BoundField DataField="Field1" HeaderText="Field1"
SortExpression="Field1" />
<asp:BoundField DataField="Field2" HeaderText="Field2"
SortExpression="Field2" />
<asp:TemplateField HeaderText="TemplateField1">
<ItemTemplate>
<asp:Label id="lblComments" runat="server" Text=" i use a function to compute"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowSelectButton="True" SelectText="Complete" HeaderText ="Status" />
<asp:TemplateField HeaderText="Action">
<ItemTemplate>
<asp:Button ID="btnComplete" runat="server" Text="Complete" onclick="btnComplete_Click"/>
<asp:Button ID="btnAddComment" runat="server" Text="Add Comment" onclick="btnAddComment_Click" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
protected void btnComplete_Click(object sender, EventArgs e)
{
String Field1 = gvGrid.SelectedRow.Cells[1].Text; // throws an error at runtime
//I want to be able to access the row data do some computation and then be able to insert it into the database
// Reason why I am trying to use it as a template field instead of a commandfield is because I want to make it not visible when it meets certain condition.
}
Also, it would be great if you could let me know a better way to do it, maybe using the command field and if there is a way to toggle its visibility. I don't mind using LinkButton either.
You can do it like this:
protected void btnComplete_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
GridViewRow gvRow = (GridViewRow)btn.Parent.Parent;
//Alternatively you could use NamingContainer
//GridViewRow gvRow = (GridViewRow)btn.NamingContainer;
Label lblComments = (Label)gvRow.FindControl("lblComments");
// lblComments.Text ...whatever you wanted to do
}
here is how you can access to the gridview row:
protected void btnComplete_Click(object sender, EventArgs e)
{
foreach (GridViewRow row in gvGrid.Rows)
{
Label lblComments = row.FindControl("lblComments") as Label;
....//you can do rest of the templatefiled....
}
}