Getting the Contents of a Gridview in Row Command - c#

This is the code in UI
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btn" runat="server" CommandName="Edit" Text="AFE" />
</ItemTemplate>
</asp:TemplateField>
--</Columns>
I Want to Get the Details of All Fields in Text boxes in Same page when ever I click on the Button Edit. I Tried using :
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Edit")
{
GridViewRow Row = (GridViewRow)(((Button)e.CommandSource).NamingContainer);
string text = Row.Cells[2].Text;
}
But I am getting "" in string text..
This is screenshot of my grid view

You can use the row index stored in command argument to find a row where Edit button is clicked.
Now you can find the TextBox in that row where cell index location is 2.
Then get the Text of your TextBox.
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if(e.CommandName == "Edit")
{
int index = Convert.ToInt32(e.CommandArgument);
GridViewRow clickedRow = CustomersGridView.Rows[index];
TextBox myTextBox = (TextBox)clickedRow.Cells[2].FindControl("TextBoxName");
string text = myTextBox.Text;
}
}
In ASPX page, you need to handle row command event like this:
<asp:gridview id="GridView1"
datasourceid="DataSource"
autogeneratecolumns="false"
onrowcommand="GridView1_RowCommand"
runat="server">
</asp:gridview>

You can access to GridViewRow using following code (note: the Button must be the control that has CommandName/CommandArgument):
var row = (GridViewRow)(((Button)e.CommandSource).NamingContainer);
Then simply use FindControl method on found row to find your target control, for ex.:
var txtSomething = (TextBox)row.FindControl("txtSomething");
Also you can access to RowIndex using row.RowIndex.
I recommended avoid using row.Cells[INDEX].FindControl(), just row.FindControl works just fine, targeting specific cell isn't good, if you change the markup and add/remove some columns, (maybe) you need to update the INDEX too, so don't do that :)

You need to find the TextBox control in the cell and get the value from it.
string text = (TextBox)Row.FindControl["MyTextBoxId"].Text;

Related

Retrieve value from DropDownList in nested GridView on RowCommand

I have a nested GridView(GvMP_Summary_Items). Each row contains a DropDownList. The DropDownList is bounded on the RowDataBound event of the nested GridView.
Each row also contains 1 Button. Upon pressing this button on the RowCommand event, I would like to find the current selected value of the DropDownList so I can use it further on in the code.
The code I have will only get the default value of the DropDownList on each row, which is currently set at 0 for each row.
Below is the RowCommand Event:
Protected Sub GvMP_Summary_Items_RowCommand(sender As Object, e As GridViewCommandEventArgs)
Dim lb As ImageButton = CType(e.CommandSource, ImageButton)
Dim gvRow As GridViewRow = lb.BindingContainer //Getting current row to get index
Dim GvMP_Summary_Items As GridView = CType(gvRow.FindControl("GvMP_Summary_Items"), GridView)
Dim intMPItem_Qty As Integer = CType(gvRow.FindControl("cboMPItem_Qty"), DropDownList).SelectedValue
Dim strMPItem_Qty As String = CType(gvRow.FindControl("txtMPItem_Qty"), TextBox).Text
End Sub
I have even included a TextBox in the GridView row which default value is empty "". Although on the row if something is entered the on RowCommand event brings back the value with a comma(,) in front of it.
This proves that I am picking up the correct row and can retrieve a value from a TextBox but not a DropDownList.
Is there something I am missing? Why can I return a value entered in a TextBox but not the selected value of a DropDownList? Also why the comma(,) in front of the TextBox value?
Note: In above case code has been written using VB so answers in VB over C# but I can accept both.
This can be done very easily by casting the CommandSource of the RowCommand back to a button and then get the correct row from that. Once you have the row you can use FindControl to locate the DropDownList. This works on every level of nested items and also on the top Control.
VB
Protected Sub GMP_Summary_Items_RowCommand(ByVal sender As Object, ByVal e As GridViewCommandEventArgs)
'cast the commandsource back to a button
Dim btn As Button = CType(e.CommandSource,Button)
'get the current gridviewrow from the button namingcontainer
Dim row As GridViewRow = CType(btn.NamingContainer,GridViewRow)
'use findcontrol to locate the dropdownlist in that row
Dim ddl As DropDownList = CType(row.FindControl("cboMPItem_Qty"),DropDownList)
'show the selected value of the dropdownlist
Label1.Text = ddl.SelectedValue
End Sub
Code was translated from C# with a code translator, so it may not be 100% accurate.
C#
protected void GMP_Summary_Items_RowCommand(object sender, GridViewCommandEventArgs e)
{
//cast the commandsource back to a button
Button btn = e.CommandSource as Button;
//get the current gridviewrow from the button namingcontainer
GridViewRow row = btn.NamingContainer as GridViewRow;
//use findcontrol to locate the dropdownlist in that row
DropDownList ddl = row.FindControl("cboMPItem_Qty") as DropDownList;
//show the selected value of the dropdownlist
Label1.Text = ddl.SelectedValue;
}
You do need to bind data to the GridView and the DropDownLists in an
IsPostBack check, otherwise the data will be rebound to the DDL on every PostBack and the selected value is lost
Important things:
Bind parent GridView in Page_Load method
Bind child GridView in parent GridView 's RowDataBound event
Bind DropDownList in child GridView 's RowDataBound event
Add CommandName to the Button which is inside child GridView
Finally, in RowCommand event of child GridView
Get child GridView 's row
Then find all controls inside child GridView from child GridView 's row
I'm not so aware of VB.NET so I have added an example (C#) of Nested GridView with RowCommand event (hope OP can use it in VB.NET):
HTML code (.Aspx):
<form id="form1" runat="server">
<asp:GridView ID="GridView_Outer" OnRowDataBound="GridView_Outer_RowDataBound" AutoGenerateColumns="false" runat="server">
<Columns>
<asp:TemplateField HeaderText="Outer Column1">
<ItemTemplate>
<asp:Label ID="Label_Outer" runat="server" Text='<%# Eval("Label_Outer") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Outer Column2">
<ItemTemplate>
<asp:GridView ID="GridView_Inner" OnRowDataBound="GridView_Inner_RowDataBound" OnRowCommand="GridView_Inner_RowCommand" AutoGenerateColumns="false" runat="server">
<Columns>
<asp:TemplateField HeaderText="Inner Column1">
<ItemTemplate>
<asp:Label ID="Label_Inner" runat="server" Text='<%# Eval("Label_Inner") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Inner Column2">
<ItemTemplate>
<asp:TextBox ID="TextBox_Inner" Text='<%# Eval("TextBox_Inner") %>' runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Inner Column3">
<ItemTemplate>
<asp:DropDownList ID="DropDownList_Inner" runat="server"></asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Inner Column4">
<ItemTemplate>
<asp:Button ID="Button_Inner" runat="server" CommandName="BtnInnerCmd" Text="Inner Button" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<br />
<asp:Label ID="Label_Result" runat="server"></asp:Label>
</form>
Code-Behind (.Aspx.cs):
DataTable TempDT = new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
CreateDataTable();
if (!IsPostBack)
{
GridView_Outer.DataSource = TempDT;
GridView_Outer.DataBind();
}
}
// create DataTable
public void CreateDataTable()
{
TempDT = new DataTable();
TempDT.Columns.Add("Label_Outer");
TempDT.Columns.Add("Label_Inner");
TempDT.Columns.Add("TextBox_Inner");
TempDT.Rows.Add("OuterLabel", "InnerLabel", "");
TempDT.Rows.Add("OuterLabel", "InnerLabel", "");
// store DataTable into ViewState to prevent data loss on PostBack
ViewState["DT"] = TempDT;
}
// Calls Outer GridView on Data Binding
protected void GridView_Outer_RowDataBound(object sender, GridViewRowEventArgs e)
{
// check if gridview row is not in edit mode
if (e.Row.RowType == DataControlRowType.DataRow)
{
// Get Outer GrridView 's controls
Label Label_Outer = (Label)e.Row.FindControl("Label_Outer");
GridView GridView_Inner = (GridView)e.Row.FindControl("GridView_Inner");
// get DataTable from ViewState and set to Inner GridView
GridView_Inner.DataSource = (DataTable)ViewState["DT"];
GridView_Inner.DataBind();
}
}
// Calls Inner GridView on Data Binding
protected void GridView_Inner_RowDataBound(object sender, GridViewRowEventArgs e)
{
// check if gridview row is not in edit mode
if (e.Row.RowType == DataControlRowType.DataRow)
{
// Get Outer GrridView 's controls
DropDownList DropDownList_Inner = (DropDownList)e.Row.FindControl("DropDownList_Inner");
// Create a DataTable to Bind data for DropDownlist
DataTable TempDDLDT = new DataTable();
TempDDLDT.Columns.Add("ItemText");
TempDDLDT.Columns.Add("ItemValue");
TempDDLDT.Rows.Add("ItemText1", "ItemValue1");
TempDDLDT.Rows.Add("ItemText2", "ItemValue2");
// bind DataTable to the DropDownList
DropDownList_Inner.DataSource = TempDDLDT;
DropDownList_Inner.DataTextField = "ItemText";
DropDownList_Inner.DataValueField = "ItemValue";
DropDownList_Inner.DataBind();
}
}
// Calls when Inner GridView 's button clicked
protected void GridView_Inner_RowCommand(object sender, GridViewCommandEventArgs e)
{
// get Inner GridView 's clicked row
GridViewRow InnerGridViewRow = (GridViewRow)(((Control)e.CommandSource).NamingContainer);
// get Inner GridView 's controls from clicked row
TextBox TextBox_Inner = (TextBox)InnerGridViewRow.FindControl("TextBox_Inner");
DropDownList DropDownList_Inner = (DropDownList)InnerGridViewRow.FindControl("DropDownList_Inner");
// check if correct button is clicked
if (e.CommandName == "BtnInnerCmd")
{
string DropDownListValue = DropDownList_Inner.SelectedValue;
string TextBoxValue = TextBox_Inner.Text;
Label_Result.Text = "DropDownList 's Selected Value is " + DropDownListValue +
"<br />TextBox 's Entered Value is " + TextBoxValue;
}
}
Demo Image:
Note: Above DropDownList selects Selected Value not Text.

How to hide a link in a cell of a gridview?

I have a gridview which displays a data from the database. In one of the tables in this database have a column to store details about attanchment file. If the attachment is available that column value will set as "YES". Otherwise it will set as "NO". What I want to do is, show a link to view the attachment. But if cell value of the column is "NO" (when there is no attachment) the link must be hidden.
Note : I know how to view a file. Here what Im expecting is to hide the link in the cell which doesn't have an attachment.
This is what I have done upto now.
if (ds.Tables[0].Rows.Count > 0)
{
grdSo.DataSource = ds;
grdSo.DataBind();
for(int i=0; i <ds.Tables[0].Rows.Count; i++)
{
if (ds.Tables[0].Rows[i][6].Equals("NO"))
{
grdSo.Rows[i].Cells[6].Visible = false;
}
else
{
grdSo.Rows[i].Cells[6].Visible = true;
}
}
}
I could hide the cell using this code. But unfortunately this hides the lines of the cell too. How can I avoid it happening?
One of the ways to do this is to use server side control like LinkButton to view the link that you want to show and set the visibility of the control as per your requirement in the OnRowDataBound event of the gridview.
Below is the code to show/hide LinkButton on OnRowDataBound event.
protected void gridId_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataSourceClass varData = (DataSourceClass)e.Row.DataItem;
// check if your data have flag to show the link
if(varData.show)
((LinkButton)e.Row.FindControl("linkbuttonId")).Visible = true;
else
((LinkButton)e.Row.FindControl("linkbuttonId")).Visible = false;
}
}
ASPX Code :
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" OnRowDataBound="GridView1_RowDataBound">
<Columns>
<asp:BoundField Visible="false" DataField="id" />
<asp:TemplateField HeaderText="Has Attachment">
<ItemTemplate>
<asp:Label ID="lblAtt" runat="server" Text='<%#Eval("HasAtt") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="View Attachment">
<ItemTemplate>
<asp:LinkButton ID="lbtnAtt" runat="server" OnClick="lbtnAtt_Click" Visible="false">View</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
CS Code :
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
this.BindGrid();
}
}
private void BindGrid()
{
//Here you write databind logic
// Datasource table of GridView1 should contain 'HasAtt' and 'id' as its binded to label.
}
private void ViewAttachment(int id)
{
//Here you write your logic to view attachment.
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow) // checking if row is datarow or not
{
Label lblHasAtt = e.Row.FindControl("lblAtt") as Label;
LinkButton lbtnViewAtt = e.Row.FindControl("lbtnAtt") as LinkButton;
lbtnViewAtt.Visible = (lblHasAtt.Text.ToLower() == "yes");
}
}
protected void lbtnAtt_Click(object sender, EventArgs e)
{
LinkButton lbtnViewAtt = sender as LinkButton;
GridViewRow grw = lbtnViewAtt.NamingContainer as GridViewRow;
int id = Convert.ToInt32(this.GridView1.Rows[grw.RowIndex].Cells[0].Text); // retriving value of first column on 'lbtnAtt' click row.
this.ViewAttachment(id);
}
I recall being able to parse through the grid view by using a for each for the rows and using a for statement for columns.
If I recall correctly, you can grab an item ie
row.Item[i]
foreach(GridViewRow row in GridView1.Rows)
{
for(int i = 0; i < GridView1.Columns.Count; i++)
{
// here you can do the logic to decide whether to show or hide the text for this cell
}
}
Sorry for formatting responding on my phone.

GridViewRow Cells returning empty strings in button Click Event fire-up inside Gridview

I am confused with this problem.
I have put a button in side the template field of a gridview and want to return the data from that specific GridView Row when that corresponding button is clicked.
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="Button2" CssClass ="btnSkin" runat="server" Text="Answer" Width="117px" onclick="Button2_Click" />
</ItemTemplate>
</asp:TemplateField>
In the button click event fireup, I want to read that data by creating a GridViewRow Element.
protected void Button2_Click(object sender, EventArgs e)
{
GridViewRow gvr = (GridViewRow)(sender as Control).Parent.Parent;
Label8.Text = gvr.Cells[1].Text;
Label10.Text = gvr.Cells[2].Text;
Label12.Text = gvr.Cells[3].Text;
}
Now the problem is, the GridViewRow Cells are returning empty strings.
What should I do?????
When using <asp:TemplateFields>, you actually need to find the text which is inside your controls such as <asp:Label> you used inside your <ItemTemplate>.
Cells won't have text, its the Controls inside the cells that have text.
So, If suppose , you have a Label inside one of your <ItemTemplate> as:
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("CustomerID") %>'>
</asp:Label>
</ItemTemplate>
Then access the Text of this Label control using below code in your button Click event:[ assuming, 2nd Column contains the above <ItemTemplate> defined ]
protected void Button2_Click(object sender, EventArgs e)
{
GridViewRow gvr = (GridViewRow)(sender as Control).Parent.Parent;
String str = ((Label)gvr.Cells[1].FindControl("Label1")).Text;
}
I found the reason behind the empty strings error.
Gridview.Cells[i].Text will return the string value only when it is a <asp:BoundField>
If it is a <asp:TemplateField> and you have some ASP control inside the <ItemTemplate>, you must follow the FindControl("<control_id>") approach.
Here, basically we look for the control object in that particular GridviewRow Cell by its ID and cast it into the corresponding Control Type. Now, we can use that as we call any other asp control from code-behind.
String str = ((Label)gvr.Cells[1].FindControl("Label1")).Text;
Try using GridView.RowCommand Event and refer the following link for the same
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.rowcommand.aspx
hope this helps you.
Please check whether you are binding the grid properly on Page Load.
if(!IsPostBack)
{
BindgridView();
}
Hope this helps..Give a try..

Gridview textbox multi line only for one single case

I am new to asp.net and I have a special issue,
I have to load a gridview from some database values...
I have 2 columns in my gridview one a label and one a textbox..
for a special value in the label the textbox should be multiline..for rest other cases the textmode should be single line...
can some one help me how to solve this issue??
PS: let me know if my question is not clear I can explain
You can use GridView.RowDataBound Event
Then find the value and if its match, you can change the property TextMode
protected void GVRowDataBound(object sender, GridViewRowEventArgs e)
{
var txb= (TextBox) e.Row.FindControl("TextBoxID");
}
You said ur new, so if in case you didn't know how to convert bound field to template field , follow this turtorial:
Tutorial
once u convert to template filed then on RowDataBound do like this:
void GridView1_RowDataBound(Object sender, GridViewRowEventArgs e)
{
foreach (GridViewRow gRow in GridView1.Rows)
{
TextBox myfieldtxt = gRow.FindControl("yourTxtBxID") as TextBox;
Label myLable = gRow.FindControl("yourLableID") as Label;
if(myLable.Text.Equals("XYZ"))
{
myfieldtxt.TextMode = TextBoxMode.MultiLine;
}
else
{
myfieldtxt.TextMode = TextBoxMode.Single;
}
}
}
You can try this way:
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" ReadOnly="True" Text='Sometext'
TextMode="MultiLine"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>

Access Non-Public members of a GridViewCommandEventArgs object

I have a gridview on my aspx page set up the OnRowCommand event using a series of ASP.NET LinkButton object to handle the logic using the CommandName property. I need to access the GridViewRow.RowIndex to retrieve values from the selected row and notice it is a non-public members of the GridViewCommandEventArgs object while debugging the application
Is there a way I can access this property of is theere a better implementation?
Here is my source code:
aspx page:
<asp:GridView ID="MyGridView" runat="server" OnRowCommand="MyGirdView_OnRowCommand">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton
id="MyLinkButton"
runat="server"
CommandName="MyCommand"
/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
code behind
protected void MyGirdView_OnRowCommand(object sender, GridViewCommandEventArgs e)
{
//need to access row index here....
}
UPDATE:
#brendan - I got the following compilation error on the following line of code:
"Cannot convert type
'System.Web.UI.WebControls.GridViewCommandEventArgs'
to
'System.Web.UI.WebControls.LinkButton'"
LinkButton lb = (LinkButton) ((GridViewCommandEventArgs)e.CommandSource);
I slightly modified the code and the following solution worked:
LinkButton lb = e.CommandSource as LinkButton;
GridViewRow gvr = lb.Parent.Parent as GridViewRow;
int gvr = gvr.RowIndex;
Not the cleanest thing in the world but this is how I've done it in the past. Usually I'll make it all one line but I'll break it down here so it's more clear.
LinkButton lb = (LinkButton) ((GridViewCommandEventArgs)e.CommandSource);
GridViewRow gr = (GridViewRow) lb.Parent.Parent;
var id = gr.RowIndex;
Basically you get your button and move up the chain from button to cell, from cell to row.
Here is the one row version:
var id = ((GridViewRow)((LinkButton)((GridViewCommandEventArgs)e).CommandSource).Parent.Parent).RowIndex;

Categories