ASP.NET - GridView - How to programmatically add and read new controls to the cell? - asp.net

Here is the setup:
I programmatically populate my gridview using LINQ to SQL query. Then I enter the edit mode and want to replace some standard TextBox controls with DropDownLists like this:
'excerpt from GridView1_RowEditing
Dim ddlist1 As New DropDownList
Dim res1 = From items1 In mydb.Items
Select items1.Col10
ddlist1.DataSource = res1
ddlist1.DataBind()
GridView1.Rows.Item(0).Cells(1).Controls.Add(ddlist1)
At this moment I have my gridview showing standard textbox control and new DDList control (in the Column 1).
The problem is -- I cant read the value from DDList in the RowUpdating method. It seems like DDList control is not in the GridView1.Rows.Item(0).Cells(1).Controls collection.
RowUpdating method sees only standard TextBox control and can read it's value.
Any suggestions are welcome. I just don't understand something here :(

Use TemplateField, and then you can locate your dropdown using FindControl
<asp:GridView ID="GridView1" runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server">
</asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
...
Protected Sub GridView1_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles GridView1.RowUpdating
Dim ddl = CType(GridView1.Rows(e.RowIndex).Cells(1).FindControl("DropDownList1"), DropDownList)
End Sub

Related

Get row values programmatically from gridview

I have a GridView Control and one button:
<asp:GridView ID="grdView" runat ="server" AutoGenerateColumns ="false" >
<Columns>
<asp:TemplateField HeaderText ="Balance">
<ItemTemplate>
<%#Eval("Balance") %>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button runat="server" ID ="btn" Text ="test"/>
Then on load page, I populate the gridView with a list of agreements. on that list there are one field called "Balance":
Private Sub form1_Load(sender As Object, e As EventArgs) Handles form1.Load
Dim agreementManager As AgreementManager = New AgreementManager()
Dim lstBalances As List(Of Agreement) = agreementManager.GetByClientId(2)
grdView.DataSource = lstBalances
grdView.DataBind()
End Sub
Then it display me this after loaded:
I am trying to read programmatically one specific balance with:
Private Sub btn_Click(sender As Object, e As EventArgs) Handles btn.Click
Dim value As String = grdView.Rows(1).Cells(0).Text
End Sub
But the "value" is empty.
What I am doing wrong?
I am working on mock a system that uses this way to read the values from a grid view, and this code works fine:
Dim balance As Decimal =
CType(grdApplyTransactionsAgreements.Rows(idx).Cells(BALANCE_CELLID).Text, Decimal)
this code is inside a button too.
Thanks!!
The .Text property can only be read after DataBinding from AutoGenerated columns and BoundField columns. But even if you could I would not recommend it since all you are getting is a string, not the original datatype.
Better read the values from the source lstBalances.
I bumped into an answer, I need to use BondField Control instead Template Field, now everything runs fine.
<asp:GridView ID="grdView" runat ="server" AutoGenerateColumns ="false" >
<Columns>
<asp:BoundField DataField ="Balance" HeaderText ="Balance"/>
</Columns>
</asp:GridView>

Call Sub Procedure using Gridview Column Imagefield

I have a Gridview column called "Path" and when the user clicks on it I want it to pass that value of the "Path" cell to a sub procedure to execute the following code,
process.start(Path)
Currently the table is filled via SQL query and the "Path" is clickable but it wants to take me to URL which won't work for my situation. I also tried the Hyperlink column as well but was having the same problem. Any guidance would be appreciated! Thanks in advance.
You could use a LinkButton instead of a HyperLink.
Set the CommandArgument on the LinkButton, you could use either the GridView.RowCommand event handler or a LinkButton.OnClick event handler to call your sub.
<asp:GridView ID="gridView" runat="server" AutoGenerateColumns="False" OnRowCommand="gridView_RowCommand">
<Columns>
<asp:TemplateField HeaderText="Path">
<ItemTemplate>
<asp:LinkButton ID="lbPath" runat="server" CommandArgument="<%# Eval("Path")%>" OnClick="lbPath_Click"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Then in code behind:
Protected Sub lbPath_Click(sender As Object, e As EventArgs)
Dim linkButton As LinkButton = CType(sender, LinkButton)
Process.Start(linkButton.CommandArgument)
End Sub
For reference
https://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.linkbutton(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.rowcommand(v=vs.110).aspx

Passing a values from Datatable to UserControl Property

I am new to programming. I'm creating a program which adds a UserControl to a Gridview template dynamically and I want to pass a value from datatable to a property of a UserControl. The TemplateField in Gridview is already preloaded with 1 user control and if I clicked on a button, this will add a new UserControl with a numbering.
Here is the code from the page on FormLoad event.
Dim dtSESRatings As New DataTable
dtSESRatings.Columns.Add("IncrementNumber")
dtSESRatings.Rows.Add("1")
ViewState("dtSESRatings") = dtSESRatings
gvSesRating.DataSource = dtSESRatings
gvSesRating.DataBind()
And I want to add the row to the Numbering label in the user control which is the IncrementNumber Property set on SESRatings.ascx.
This is the asp code:
<asp:GridView ID="gvSesRating" runat="server" Width="100%" ShowHeader="false" GridLines="None"
AutoGenerateColumns="False">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<ses:SESRatings runat="server" ID="ses1" IncrementNumber="1" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
After FormLoad, upon clicking on a button "ADD NEW RATING", it is supposed to create a new user control in the gridview and the code is here:
Protected Sub btnAddRating_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnAddRating.Click
Dim dt As DataTable = ViewState("dtSESRatings")
Dim dtCnt As Integer = dt.Rows.Count
dtCnt += 1
dt.Rows.Add(dtCnt)
ViewState("dtSESRatings") = dt
gvSesRating.DataSource = dt
gvSesRating.DataBind()
dt = Nothing
End Sub
I want that the user control that will be added in the GridView will get the dtCnt and pass it to the IncrementNumber Property of the User Control. How can I do that? Please help. Thanks.
you must use Eval tags in your gridview control:
<ses:SESRatings runat="server" ID="ses1" IncrementNumber='<%# Eval("IncrementNumber") %>' />

Using FindControl method of FormView within a Repeater

I need an advice how to correct my code. I am using FindControl method to find TextBox inside Repeater. This is my markup:
<asp:Repeater ID="Repeater1">
HERE ARE SOME OTHER DATA
<ItemTemplate>
<asp:FormView ID="FormViewAddComment" runat="server"
DataSourceID="SqlDataSourceInsertComments" DefaultMode="Insert"
OnItemInserted="FormViewAddComment_ItemInserted"
OnItemInserting="FormViewAddComment_ItemInserting">
<InsertItemTemplate>
<asp:TextBox ID="txtAddComment" runat="server" CssClass="textbox"
Text='<%# Bind("CommentText") %>' Width="200px" />
<asp:Button ID="btnAddComment" runat="server" CssClass="button"
Text="Comment" CommandName="Insert" CausesValidation="false"/>
</InsertItemTemplate>
</asp:FormView>
</ItemTemplate>
</asp:Repeater>
And this is my code behind:
Protected Sub FormViewAddComment_ItemInserting(sender As Object, e As FormViewInsertEventArgs)
Dim FormView As FormView = DirectCast(Repeater1.FindControl("FormViewAddComment"), FormView)
Dim Comment As TextBox = DirectCast(FormView.FindControl("txtAddComment"), TextBox)
If Comment.Text = "" Then
Exit Sub
End If
End Sub
The Comment TextBox is not found and the code throws an Object reference error when it tries to access the Text property.
You can find the textbox inside it using ItemDataBound event.
Thanks
You are accessing "txtAddComment" which is there in FormView,then why are you finding FormView in Repeater and then again in textbox in that...you can directly find out it...
Protected Sub FormViewAddComment_ItemInserting(sender As Object, e As FormViewInsertEventArgs)
If (FormView1.CurrentMode == FormViewMode.Insert)
Dim Comment As TextBox = DirectCast(FormViewAddComment.FindControl("txtAddComment"), TextBox)
If Comment.Text = "" Then
Exit Sub
End If
End Sub
EDIT:-
My point is that you are writting the code in ItemInserting Event of FormView,so there you can directly find the FormView.I would suggest to use NamingContainer property in oredr to find the FormView which has trigged the event,by this way you can find the FormView then you can easily find the TextBox in it.
There is example of NamingContainer for Gridview Here

Problem finding web control inside of Gridview TemplateField

Okay, so I'm having issues getting the value of a DropDownList that's inside of a TemplateField when updating my GridView. Originally I was using the RowCommand event to check the command name and then performing the appropriate task (update/delete), but I had problems with the event firing twice, so I switched it out for separate events (RowUpdating, RowDeleting). After doing this, FindControl is returning null every time. Just FYI, the gridview is inside of an UpdatePanel that has an AsyncPostBackTriggers for RowEditing, RowUpdating and RowDeleting events.
Here's my TemplateField inside of the GridView:
<asp:TemplateField HeaderText="Type">
<ItemTemplate>
<asp:Label
ID="lblMedTypeEdit"
Text='<%# Bind("medDesc") %>'
runat="server">
</asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList
ID="ddlMedTypeEdit"
DataSourceID="srcMedTypes"
SelectedValue='<%# Bind("medtype") %>'
runat="server"
DataTextField="medDesc"
DataValueField="medCode">
</asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
Here is the code I'm using inside of
Protected Sub gvCurrentMeds_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles gvCurrentMeds.RowUpdating
Dim intRowIndex As Integer = e.RowIndex
Dim ddlMedType As DropDownList = CType(Me.gvCurrentMeds.Rows(intRowIndex).Cells(1).FindControl("ddlMedTypeEdit"),DropDownList)
End Sub
I also tried using a recursive function to find the control (below), but it is still returning back null.
Public Function FindControlRecursive(ByVal root As Control, ByVal id As String) As Control
If root.ID = id Then
Return root
End If
For Each c As Control In root.Controls
Dim t As Control = FindControlRecursive(c, id)
If Not t Is Nothing Then
Return t
End If
Next
Return Nothing
End Function
If you just want to know what the new value of the dropdown is, this is already provided for you in the NewValues property of the GridViewUpdateEventArgs object passed to the event handler.
In your example, e.NewValues["medtype"] should be the updated value.
You've already specified <%# Bind(...) %> on the dropdown, so ASP.NET will do the work of finding the controls and getting the new values for you - you don't have to plumb the control hierarchy yourself.

Resources