Link to home
Start Free TrialLog in
Avatar of taylor99
taylor99

asked on

Gridview Empty Data template How to capture data

Hi All,

I have a gridview which includes a databound textbox (located in the footer of the grid) which is used to search a database, this control works prefectly using the code below to capture the search text.

Dim ProdName = TryCast(GridView3.FooterRow.FindControl("ProductSearchTB"), TextBox)
        SqlDataSource4.SelectParameters("PROD_DESC").DefaultValue = ProdName.Text

My issue is this, I need to be able to run the same search from an empty Gridview, I originally tried
        Dim ProdName = TryCast(GridView3.EmptyDataTable.FindControl("NewProductSearchTB"), TextBox)
        SqlDataSource4.SelectParameters("PROD_DESC").DefaultValue = ProdName

But get the following error
'EmptyDataTable' is not a member of 'System.Web.UI.WebControls.GridView'.      

Is there another way to capture the search text rather than using FindControl?

Many Thanks
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

How is the GridView defined in HTML?
ASKER CERTIFIED SOLUTION
Avatar of abel
abel
Flag of Netherlands image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
The problem is that when your datatable is empty, your footerrow doesn't exist.
Can you show me how you defined your section: <EmptyDataTemplate></EmptyDataTemplate> ?

My guess is that you placed an asp:table named "EmptyDataTable", and inside of it you have this NewProductSearchTB.  If this is the case you need to do this
Dim et as Table
Dim tb as TextBox
et = CType(GridView3.FindControl("EmptyDataTable"), Table)
tb = CType(et.FindControl("NewProductSearchTB"), TextBox)
... then whatever you want with your tb textbox

Note, the first Controls[0] is of type ChildTable. The second Controls[0] returns a type GridViewRow, which contains your EmptyDataTemplate.

One might be tempted to do something like this:

GridView3.EmptyDataTemplate.FindControl
but that's only the template, not the naming container. As a result, it cannot find your control for you.
Btw, considering the assumed confusion about EmptyDataTable: I assumed you mistyped that and meant EmptyDataTemplate and that you had something like this, which will work with the code I showed:

<asp:GridView ...decl...>
   <.. other controls ..>
 
   <EmptyDataTemplate>
	<asp:TextBox runat="server" 
		text="hello"
		ID="newProductSearchTB"/>
   </EmptyDataTemplate>	
		
</asp:GridView>

Open in new window

As abel said, in his solution, the cell must be empty (no other thing than your TexBox).  So if you add a label beside your textbox, make sure that you point to the right control index.  I would rather use a FindControl approach even if you don't like it.

If you don't like this FindControl approach, you could use this new version which find a control even if its in a sub-sub-sub item :)
    Private Function FindControlRecursive(ByVal root As Control, ByVal id As String) As Control
        If root Is Nothing Then
            Return Nothing
        End If
        If root.ID = id Then
            Return root
        End If
        Dim c As Control
        For Each c 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

Open in new window

You can use this FindControlRecursive like this:

Dim tb as Textbox
tb = CType(FindControlRecursive(GridView3, "NewProductSearchTB"), TextBox)
Yes, that's a nice solution. It's quite a well-known technique and it your code is explained here: http://www.devx.com/vb2themax/Tip/19449

> As abel said, in his solution, the cell must be empty (no other thing than your TexBox).

That was not what I meant. You can have hundredths of controls inside the EmptyDateTemplate, in fact, you can have them anywhere. Otherwise, the FindControl in my code would not have been necessary.

If there is data in the grid, the code will simply return Nothing, all you need to check for is the returned value:

If IsNothing(tb) Then
   ...


etc.

In other words: it will return the textbox is there is no data, and it will return nothing if there is data. In short: the returned value is always usable.
One issue not touched on in this thread so far is that of the events. We have seen little of the actual ASPX (nothing, actually), but if you need this TextBox as the result of someone clicking on a button which is located inside the EmptyDataTemplate, there's a very direct way to get to your TextBox, and if you are in this situation, I recommend using this direct technique:




Protected Sub myButton_Click(ByVal sender As Object, ByVal e As EventArgs)
    Dim tb As TextBox = CType(CType(sender, Button) _
        .NamingContainer.FindControl( _
        "newProductSearchTB"), TextBox)
End Sub

Open in new window

Looking further into this, there appear to be more and more ways to get this information. Strange that this intel is so scattered about on the internet. So, after:

method #1: using Control[0].Control[0].FindControl (not pretty, but stable)
method #2: using FindControlRecursive (has the danger of finding duplicates)
method #3: using an event of another control inside EmptyDataTemplate
method #4: using GridView_RowDataBound event (see below)

In the GridView_RowDataBound event, it is trivial to check for the row type, and if it is the correct type, you immediately have the correct typed object at your disposal:

    Protected Sub GridView3_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView3.RowDataBound
        If e.Row.RowType = DataControlRowType.EmptyDataRow Then
            Dim tb As TextBox = DirectCast(e.Row.FindControl("newProductSearchTB"), TextBox)
        End If
    End Sub

Open in new window

The chances to find a duplicate in an EmptyDataTemplate is as big as messing up with Controls index.

But i think that Taylor got the idea and have enough solutions.  
> The chances to find a duplicate in an EmptyDataTemplate is as big as messing up with Controls index.

agreed, unless in this case the controls-array is fixed for the very first controls that are added due to the design of GridView. But there's a naming-clash possibility if a row contains an item of the same name when the datasource is non-empty.

So, basically, if you want to be on the sure side, you need to use the control's events, or the RowDataBound event (and maybe there are still many other methods?).

Interesting thread, learning something here... ;)
unless == although
I think i already tried all theses solutions in the past.  As you said, there's so much methods on the net.  I had my problem in the past trying to figure out what was the best way.

I like to use the RowDataBound method to add some javascript onclick action (to confirm a delete for example)
Avatar of taylor99
taylor99

ASKER

Perfect, thanks abel
pls abel, next time... tell me to not get into this kind of thread :-).  lol.
@OP: glad we could be of some help :)


> pls abel, next time... tell me to not get into this kind of thread :-).  lol.
why not? Though the question should've been closed with a split points... Why it isn't I don't know.
Because obviously, the askers tried the first thing that he saw, even if others took some of their week-end time to answer them.  

I start to think that i should just keep myself over the 3000 points per month and that's it.  Got 46500 points this month, but i'll never get to Guru level with that kind of askers
don't get grumpy, it's a sunny day (well, here it is). If the original asker is still around, (s)he can request a reopening of the question by clicking "request attention". After reopening (s)he can split the points.

@taylor99, to prevent this in the future, please read: https://www.experts-exchange.com/help.jsp?hi=407 on closing questions and this: https://www.experts-exchange.com/help.jsp#hi100 on splitting points
There's no need to re-open the question, i'll live with few points less.  

But thanks for giving him links explaining how to split points.