I have a DataView control. I have a Template Field named MyNewTemplateField and in it's Edit Items Template I have a text box called "txtMyTextBox", which I want to do something with the data typed in, and then take that result and put it in the Access database.
Protected Sub DataView1_ItemCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewCommandEventArgs) Handles dvAcct.ItemCommand Select Case e.CommandName Case "Edit" Dim txtTheText As New TextBox txtTheText = DataView1.FindControl("txtMyTextBox") txtTheText.Text = "hello" End Select End Sub
ok, I get an error on txtTheText.Text = "hello" saying I have to use "New" to create a new instance. Looking at the txtTheText, it is set to "nothing" by the time it gets to the "hello" line. This means it didn't find the control?How do I get it to find the control?
![]() |
0 |
![]() |
I meant DetailsView control, not DataView. Sorry.
![]() |
0 |
![]() |
Hi, FuzzieDice:
Do you use use a DetailsView? I have not seen the DataView as the control in the Tool Box.
If so, you can try to set the RowState of the particular row to Edit adn then you can use FindControl to access the controls in the EditTemplate.
Best Regards,
__________________________________________________
Sincerely,
Rex Lin
Microsoft Online Community Support
If there is any question or the issue is not resolved, please feel free to mark the thread as not resolved
![]() |
0 |
![]() |
Yes, I'm using the DetailsView. Sorry about the typo.
I don't understand what you're saying at all. I can't find the control. It's already in Edit mode as shown in my code above so I don't know what you mean by setting it as it's already editing the field. I need to figure out how to get the information out of the textbox. It doesn't show up in the properties unless I'm in design mode and editing the EditTemplate. Then it shows up as:
DetailsView1.Field12MyNewTemplateField.EditItemTemplate.txtMyTextBox
But it's not in the drop down in the code view.
![]() |
0 |
![]() |
Yes. When you do the findcontrol in the command event, it will get the reference to the control in the ItemTemplate instead of the on in the EditTemplate. So you can try to set the RowState of this particular row and then you can use findcontrol to access your control in the EditTemplate.
this.DetailsView1.Rows[1].RowState = DataControlRowState.Edit;
// use findcontrol here/
Best Regards,
__________________________________________________
Sincerely,
Rex Lin
Microsoft Online Community Support
If there is any question or the issue is not resolved, please feel free to mark the thread as not resolved
![]() |
0 |
![]() |
That is not Visual Basic. I'm using Visual Basic.
I tried it this way trying to figure out your C Code.
DetailsView1.Rows(12).RowState = DataControlRowState.Edit
It says that the RowState is ReadOnly. So I can not set the row state.
So this doesn't work.
![]() |
0 |
![]() |
I've figured it out. There was an article (now I forgot where) that said that you can't use FindControl because template controls are assigned IDs and runtime. So, you have to do this via code such as this:
1 If DetailsView1.CurrentMode = DetailsViewMode.Edit Then 2 For Each dvr As DetailsViewRow In dvAcct.Rows 3 Dim intCellCount As Integer 4 intCellCount = dvr.Cells.Count 5 If intCellCount = 2 Then 6 Dim intCtrlCount, i As Integer 7 intCtrlCount = dvr.Cells(1).Controls.Count 8 If intCtrlCount > 0 Then 9 For i = 0 To intCtrlCount - 1 10 Dim txt As Control 11 Dim tpe As Type 12 txt = dvr.Cells(1).Controls(i) 13 tpe = txt.GetType 14 If tpe.Name = "TextBox" Then 15 Dim txtBox As TextBox 16 txtBox = txt 17 Dim strText, strID As String 18 'Break at the end of the next two lines and hover over the str 19 'variables to see the contents. 20 strText = txtBox.Text 21 strID = txtBox.ID 22 End If 23 Next 24 End If 25 End If 26 Next 27 End IfBreakpoint at line 22 then hover over the str variables in lines 20 and 21, you'll see what is in the text boxes. This can be adapted to look at other controls. Just use if tpe.name <> "LiteralControl" in line 14 and make any necessary adjustments and tests to consider text boxes, check boxes, and the like.
Then one could add custom code and manually update the database.
One last note: It's best to go in and edit the fields, and convert them all to TemplateFields, then go into each field's EditTemplate and click on the control. Then give it a name in the ID property. This way, the txtBox.ID in line 21 won't come up as '(nothing)' and you could reference it if you need to.
![]() |
0 |
![]() |
FuzzieDice:
template controls are assigned IDs and runtime.
Should read:
template controls are assigned IDs at runtime.
I wish there was a way to edit our posts in this forum.
![]() |
0 |
![]() |
Ok, I've cleaned up the code a little bit and made it a function which you can use in any dataview control:
'Get Data From DetailsView Public Function GetDetailsViewData(ByVal dvControl As DetailsView) As ArrayList Dim arrData As New ArrayList For Each dvr As DetailsViewRow In dvControl.Rows If dvr.Cells.Count = 2 Then If dvr.Cells(1).Controls.Count > 0 Then For Each ctrlControl As Control In dvr.Cells(1).Controls Select Case ctrlControl.GetType.Name Case "TextBox" Dim txtBox As TextBox txtBox = ctrlControl arrData.Add(Trim(txtBox.Text)) Case "CheckBox" Dim chkBox As CheckBox chkBox = ctrlControl arrData.Add(chkBox.Checked.ToString) Case "DropDownList" Dim cmbBox As DropDownList cmbBox = ctrlControl arrData.Add(cmbBox.SelectedValue) End Select Next End If End If Next Return arrData End FunctionTo use it, just do the following:
Protected Sub DataView1_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles DataView1.PreRender If DataView1.CurrentMode = DetailsViewMode.Edit Then 'Get Data Dim arrData As New ArrayList arrData = sMod.GetDetailsViewData(DataView1) End If End Sub
![]() |
0 |
![]() |
Ok, I have been fiddling with it some more and I have now finally got a subroutine that let's you access and return the actual control! :)
Here's the steps:
1. In your details view, edit the cells and make every one of them which you need to access - convert to template.
2. Now edit the template for item and edit item. Click on the controls and give them names you can remember (write them down, is best or type in a text editor and print them out for reference). This is important as you'll need these names to access the controls.
3. Add this code to your project either as a separate class or in your page as a separate function:
Public Function DVFindControl(ByVal dvControl As DetailsView, ByVal strControlID As String) As Control Dim ctlTarget As New Control For Each dvr As DetailsViewRow In dvControl.Rows If dvr.Cells.Count = 2 Then If dvr.Cells(1).Controls.Count > 0 Then For Each ctrlControl As Control In dvr.Cells(1).Controls If ctrlControl.GetType.Name <> "LiteralControl" Then If ctrlControl.ID = strControlID Then ctlTarget = ctrlControl Return ctlTarget End If End If Next End If End If Next Return ctlTarget End Function4. Use this function in your program:
Dim EControl As New Control Dim EtxtBox As New TextBox ' Or whatever control you are accessing EControl = DVFindControl(DetailsView1, "txtMyTextBox") EtxtBox = EControl5. Now you can access the control just like you would any other, ie: txtMyTextBox.Text, etc.
But there you have it. This will work on any control you need to find embeded somewhere in the DetailsView.
Warning: (Yes, there has to be one of those too). Be very sure that you are in the right view mode! The access code probably should be put in your DetailsView's PreRender event. Otherwise it won't find the control.
I hope that this will help others that run into this problem. Thank you to those who replied as it did give me some starting points.
![]() |
0 |
![]() |
How could I get this to work for a GridView?
Kind Regards,
James
![]() |
0 |
![]() |
You're in luck. :) Here's my routine that I use for GridView controls. It's a bit different since GridViews are a little different:
This returns the control, as does my last example, so you can directly access the control the same way when the control is returned by the function below.
Public Function GVFindControl(ByVal gvControl As GridView, ByVal intRow As Integer, ByVal strControlID As String) As Control Dim ctlTarget As New Control For Each dvr As GridViewRow In gvControl.Rows If gvControl.Rows(intRow).Cells(0).Controls.Count > 0 Then For Each ctrlControl As Control In gvControl.Rows(intRow).Cells(0).Controls If ctrlControl.GetType.Name <> "LiteralControl" Then If ctrlControl.ID = strControlID Then ctlTarget = ctrlControl Return ctlTarget End If End If Next End If Next Return ctlTarget End Function
![]() |
0 |
![]() |
Is there any point in particular I should call this function from?
Regards,
James
![]() |
0 |
![]() |
Hi, I've just had a quick go and get the following error:
Unable to cast object of type 'System.Web.UI.Control' to type 'System.Web.UI.WebControls.TextBox'.
Any ideas?
Regards,
James
![]() |
0 |
![]() |
Ok, try this code function. Save it to a class file such as LocateControls.vb and include it in your project.
Public Class LocateControls
Public Function GVFindControl(ByVal gvControl As GridView, ByVal intRow As Integer, ByVal intColumn As Integer, ByVal strControlID As String) As Control Dim ctlTarget As New Control For Each dvr As GridViewRow In gvControl.Rows If gvControl.Rows(intRow).Cells(intColumn).Controls.Count > 0 Then For Each ctrlControl As Control In gvControl.Rows(intRow).Cells(intColumn).Controls If ctrlControl.GetType.Name <> "LiteralControl" Then If ctrlControl.ID = strControlID Then ctlTarget = ctrlControl Return ctlTarget End If End If Next End If Next Return ctlTarget End FunctionEnd Class
Now, to call it you first have to define some variables:
Dim lc As New LocateControls 'Let's assume we are looking for a label control 'But it can be anything. Dim lblMyLabel As New Label 'These are used in my counter loop below Dim i as Integer Dim blnFlag as BooleanNow before you call the function, here are the parameters it will need, in order Left to Right:
1. The ID or Name of the GridView Control. For this example, lets use GridView1.
2. The Row you want to retrieve. Or you can iterate through all rows in a for/next loop as I will in this example.
3. The Column where the control will be found. This is very important. I think this is why the old version of the function was throwing errors sometimes, because it wasn't found. Columns start at 0 on the left.
4. The name of the control you're looking for, enclosed in quotes. Here I'm looking for "lblMyLabel"
So now, let's use some code to find this control. Notice I'm using some exception handling here. This is necessary just in case you can't find the control because there's no other way to tell.
For i = 0 To GridView1.Rows.Count - 1 Try 'I'm going to assume that the 4th column in the gridview (Column 3) 'Is where my control is found. lblMyLabel = lc.GVFindControl(GridView1, i, 3, "lblMyLabel") blnCtlFlag = True Catch ex As Exception 'The control wasn't found! blnCtlFlag = False Exit For End Try If blnCtlFlag = True Then lblMyLabel.Text = "This is my control!" End If NextWhat is happening here is that it is iterating through all the rows in one particular column to find a control by the name we specify. Then it sets the text to "This is my control!"
If you are very certain that it will always find the control in every row of a column (such as a label to denote yes/no, etc.) then you can probably leave out the exception handling bit. However, if some rows in the column have the control and some don't, you'll need to do exception handling.
I can't figure out any other way for the program to pass information back on whether or not the control was found. It just passes back the control. So you'll have to do some error checking on your own there.
Hope this helps!
![]() |
0 |
![]() |
Hi,
u have provided nice code ...
but after using your code ... still i m not able to locate a listbox lying within EditItemTemplate of a Gridview...
I have following TemplateField of Gridview ...
<
asp:TemplateField> <ItemTemplate> <asp:Label ID="lblHost" runat="server" Text='<%# Eval("HostFrom") %>'></asp:Label> </ItemTemplate> <EditItemTemplate> <asp:ListBox ID="lstHost" runat="server" SelectionMode="Multiple"> <asp:ListItem Value="TC" Text="Tenders"></asp:ListItem> <asp:ListItem Value="GT" Text="Global"></asp:ListItem> <asp:ListItem Value="CC" Text="Projects"></asp:ListItem> </asp:ListBox> </EditItemTemplate> </asp:TemplateField>
I am not able to locate the listbox control ... and one more thing I want to know is from which event I should call the function given by you... possible thru RowEditing or something else ... and I am not sure about whether it is possible or not ...
Plz help me to come out the situation ...
Thanks & Regards,
Krupa Parikh
![]() |
0 |
![]() |
Ok, I've tried your code and cannot get it to work properly, it will work on the first row in the GridView, but no others! Can you think of any reason why this would be?
Kind regards,
James
![]() |
0 |
![]() |
This is weird, because I have no trouble at all performing a FindControl() for an Edit ItemTemplate field on my DetailsView.
For instance, in my DetailsView1 control I have an "Item Description" field which is a Label in "ReadOnly" mode and an HTMLTextArea in "Edit" and "Insert" modes.
If I want to find the user's input into the TextArea (to perform my update), I call:
Dim textarea1 As HTMLTextArea = DetailsView1.FindControl("TextArea1")
Then I can do:
dsDV1.UpdateCommand = "UPDATE [tblItems] SET [ItemDescription] = '" & textarea1.Value & "' WHERE [ItemID] = " & selectedItem.ID
Is this a fluke, or am I missing something?
![]() |
0 |
![]() |