Solution to the FindControl problemhttp://forums.asp.net/t/1107107.aspx/1?Solution+to+the+FindControl+problemFri, 01 Jan 2010 20:32:00 -050011071071696269http://forums.asp.net/p/1107107/1696269.aspx/1?Solution+to+the+FindControl+problemSolution to the FindControl problem <p>I have seen may posts about having problems with the FindControl method. Most seem to come about because the control being searched for is nested within a container other than the webform.</p> <p>I came across this code (sorry dont remember the web site)&nbsp; that I have posted in response to many of the posts related to this type of problem. I thought it would be easier if I post this code here for others to find.</p> <p><font color="#808080" size="2"><font color="#808080" size="2">///</font><font color="#008000" size="2"> </font><font color="#808080" size="2">&lt;summary&gt;</font><font size="2"> </font></p> &lt;div class=ForumPostContentText id=ctl00_ctl01_bcr_ctl00___PostRepeater_ctl02_PostViewWrapper&gt; &lt;div class=ForumPostContentText id=ctl00_ctl01_bcr_ctl00___PostRepeater_ctl02_PostViewWrapper&gt; <p><font color="#808080" size="2">///</font><font color="#008000" size="2"> Finds a Control recursively. Note finds the first match that exists</font><font size="2"> </font></p> <p><font color="#808080" size="2">///</font><font color="#008000" size="2"> </font> <font color="#808080" size="2">&lt;/summary&gt;</font><font size="2"> </font></p> <p><font color="#808080" size="2">///</font><font color="#008000" size="2"> </font> <font color="#808080" size="2">&lt;param name=&quot;ContainerCtl&quot;&gt;</font><font color="#008000" size="2">Should be the lowest container in the heirarchy, for eg dont choose Master page if you can pick the specific panel</font><font color="#808080" size="2">&lt;/param&gt;</font><font size="2"> </font></p> <p><font color="#808080" size="2">///</font><font color="#008000" size="2"> </font> <font color="#808080" size="2">&lt;param name=&quot;IdToFind&quot;&gt;</font><font color="#008000" size="2">ID of the control you are looking for</font><font color="#808080" size="2">&lt;/param&gt;</font><font size="2"> </font></p> <p><font color="#808080" size="2">///</font><font color="#008000" size="2"> </font> <font color="#808080" size="2">&lt;returns&gt;</font><font color="#008000" size="2">the control if found else null</font><font color="#808080" size="2">&lt;/returns&gt;</font><font size="2"> </font></p> <p><font color="#0000ff" size="2">private</font><font size="2"> </font><font color="#0000ff" size="2">static</font><font size="2"> </font><font color="#008080" size="2">Control</font><font size="2"> FindControlRecursive(</font><font color="#008080" size="2">Control</font><font size="2"> Root, </font><font color="#0000ff" size="2">string</font><font size="2"> Id) </font></p> <p>{</p> <p><font color="#0000ff" size="2">if</font><font size="2"> (Root.ID == Id) </font> </p> <p><font color="#0000ff" size="2">return</font><font size="2"> Root; </font></p> <p><font color="#0000ff" size="2">foreach</font><font size="2"> (</font><font color="#008080" size="2">Control</font><font size="2"> Ctl </font><font color="#0000ff" size="2">in</font><font size="2"> Root.Controls) </p> <p>{</p> <p></font><font color="#008080" size="2">Control</font><font size="2"> FoundCtl = FindControlRecursive(Ctl, Id); </p> <p></font><font color="#0000ff" size="2">if</font><font size="2"> (FoundCtl != </font> <font color="#0000ff" size="2">null</font><font size="2">) </p> <p></font><font color="#0000ff" size="2">return</font><font size="2"> FoundCtl; </p> <p>}</p> <p></font><font color="#0000ff" size="2">return</font><font size="2"> </font><font color="#0000ff" size="2">null</font><font size="2">; </p> <p>}</p> </font>&lt;/div&gt;</font>&lt;/div&gt; 2007-05-05T11:12:47-04:001697604http://forums.asp.net/p/1107107/1697604.aspx/1?Re+Solution+to+the+FindControl+problemRe: Solution to the FindControl problem <p>hi friend...</p> <p>thanks for the snippet... would be help ful...&nbsp;</p> 2007-05-07T04:37:57-04:001757118http://forums.asp.net/p/1107107/1757118.aspx/1?Re+Solution+to+the+FindControl+problemRe: Solution to the FindControl problem <p>I don't really understand this explanation; it is rather cryptic and I understand C# a little, but I wish it were in VB.</p> <p>&nbsp;</p> <p>Are you saying that first we need to find the webform, then formview, and then the button in my case?&nbsp; Why do I need todo that, andyway it doesn't work.</p> <p>&nbsp;</p> <p>I I tried writing this in VB but was stumped as to how you call FindControlRecursive from within itself?</p> <p>&nbsp;</p> 2007-06-15T18:42:33-04:001757563http://forums.asp.net/p/1107107/1757563.aspx/1?Re+Solution+to+the+FindControl+problemRe: Solution to the FindControl problem <p>CiscoCylk I have dug up the post that I originally found the code at </p> <p><a href="http://www.west-wind.com/WebLog/posts/5127.aspx">http://www.west-wind.com/WebLog/posts/5127.aspx</a> he provides some info on why the problem occurs.</p> <p>Basically I first hit this problem when I started using some of the new Login control provided with ASP.NET 2.0. It seems like they inlcude an additional container that hides the controls within so that doing a FindControl at the page level doesnt pick them up.</p> <p>The code does work for me, on a number of occasions and a number of different applications, so if you would care to post up how you are trying to use the code I could offer an opinion.</p> <p>Not sure about the 3rd part of your question, as to how I call FindControlRecursive from within itself. Do you mean that you dont understand recursion or is there something else you dont understand</p> 2007-06-16T06:01:15-04:001763143http://forums.asp.net/p/1107107/1763143.aspx/1?Re+Solution+to+the+FindControl+problemRe: Solution to the FindControl problem <p>This is true, solution may be your or that:</p> <p><a href="http://www.codinghorror.com/blog/archives/000307.html">http://www.codinghorror.com/blog/archives/000307.html</a></p> <p>&nbsp;But recursion is expensive, so better will be:</p> <font size="1"></font><font color="#0000ff" size="1">private</font><font size="1"> </font><font color="#0000ff" size="1">static</font><font size="1"> </font><font color="#2b91af" size="1">Control</font><font size="1"> FindControlIterative(</font><font color="#2b91af" size="1">Control</font><font size="1"> root, </font><font color="#0000ff" size="1">string</font><font size="1"> id)</font><font size="1"> <p>{</p> </font><font color="#2b91af" size="1">Control</font><font size="1"> ctl = root;</font><font size="1"> <p></font><font color="#2b91af" size="1">LinkedList</font><font size="1">&lt;</font><font color="#2b91af" size="1">Control</font><font size="1">&gt; ctls = </font><font color="#0000ff" size="1">new</font><font size="1"> </font><font color="#2b91af" size="1">LinkedList</font><font size="1">&lt;</font><font color="#2b91af" size="1">Control</font><font size="1">&gt;();</p> </font><font color="#0000ff" size="1">while</font><font size="1"> (ctl != </font> <font color="#0000ff" size="1">null</font><font size="1">)</font><font size="1"> <p>{</p> </font><font color="#0000ff" size="1">if</font><font size="1"> (ctl.ID == id)</font><font size="1"></font><font color="#0000ff" size="1">return</font><font size="1"> ctl;</font><font size="1"> <p>&nbsp;</p> </font><font color="#0000ff" size="1">foreach</font><font size="1"> (</font><font color="#2b91af" size="1">Control</font><font size="1"> child </font><font color="#0000ff" size="1">in</font><font size="1"> ctl.Controls)</font><font size="1"> <p>{</p> <p></font><font color="#0000ff" size="1">if</font><font size="1"> (child.ID == id)</p> </font><font color="#0000ff" size="1">return</font><font size="1"> child;</font><font size="1"></font><font color="#0000ff" size="1">if</font><font size="1"> (child.Controls.Count &gt; 0)</font><font size="1"> <p>ctls.AddLast(child);</p> <p>}</p> </font><font color="#0000ff" size="1">if</font><font size="1"> (ctls.Count &gt; 0)</font><font size="1"> <p>{</p> <p>ctl = ctls.First.Value;</p> <p>ctls.Remove(ctl);</p> <p>}</p> <p></font><font color="#0000ff" size="1">else</p> </font><font size="1">ctl = </font><font color="#0000ff" size="1">null</font><font size="1">;</font><font size="1"> <p>}</p> </font><font color="#0000ff" size="1">return</font><font size="1"> </font><font color="#0000ff" size="1">null</font><font size="1">;</font><font size="1"> <p>}</p> </font> 2007-06-20T08:50:48-04:001763165http://forums.asp.net/p/1107107/1763165.aspx/1?Re+Solution+to+the+FindControl+problemRe: Solution to the FindControl problem <p>Better version is bellow<pre class="prettyprint">private static Control FindControlIterative(Control root, string id) { Control ctl = root; LinkedList ctls = new LinkedList(); while (ctl != null) { if (ctl.ID == id) return ctl; foreach (Control child in ctl.Controls) { if (child.ID == id) return child; if (child.HasControls()) ctls.AddLast(child); } ctl = ctls.First.Value; ctls.Remove(ctl); } return null; }</pre>&nbsp;</p> 2007-06-20T09:03:34-04:001765398http://forums.asp.net/p/1107107/1765398.aspx/1?Re+Solution+to+the+FindControl+problemRe: Solution to the FindControl problem <p>&nbsp;<pre class="prettyprint">private static Control FindControlIterative(Control root, string id) { Control ctl = root; LinkedList ctls = new LinkedList(); while (ctl != null) { if (ctl.ID == id) return ctl; foreach (Control child in ctl.Controls) { if (child.ID == id) return child; if (child.HasControls()) ctls.AddLast(child); } ctl = ctls.First.Value; ctls.Remove(ctl); } return null; }</pre>&nbsp;</p> 2007-06-21T09:23:02-04:001918954http://forums.asp.net/p/1107107/1918954.aspx/1?Re+Solution+to+the+FindControl+problemRe: Solution to the FindControl problem <p>Question?? Don't most of the controls you can nest other controls in have a FindControl method?? If you already have the id of the control you want and I assume an idea of the id for the controls container why could you not use the built in methods to search for this control??</p> 2007-09-20T16:57:21-04:001938572http://forums.asp.net/p/1107107/1938572.aspx/1?Re+Solution+to+the+FindControl+problemRe: Solution to the FindControl problem <p>&nbsp;I don't understand how you use the code you posted - where do you type that? Also, can someone translate to VB please?<br> </p> 2007-10-03T12:51:56-04:001943757http://forums.asp.net/p/1107107/1943757.aspx/1?Re+Solution+to+the+FindControl+problemRe: Solution to the FindControl problem <p>There's some irony to be noted here. If you read Scottgu's comment at the top,&nbsp;he says that they debated sticking in a recursive FindControl(), but decided against it because of the&nbsp;potential for newbies to start abusing it and thereby negatively affecting their page's performance. What's ironic is that people went ahead and did what MS didn't want&nbsp;-- wrote their own recursive methods to find controls!</p> <p>Either way we get the shaft. Use recursion to find a control and you're going to pay for it in terms of performance. Use FindControl(&quot;ctl00&quot;).FindControl(&quot;whatever&quot;).FindControl(&quot;whatever2&quot;) and you won't pay the performance price, but it could come back to haunt you in the future should you&nbsp;add even one more layer (i.e. - panel, user control, etc.) inbetween.</p> 2007-10-05T22:51:24-04:001958163http://forums.asp.net/p/1107107/1958163.aspx/1?Re+Solution+to+the+FindControl+problemRe: Solution to the FindControl problem <p></p> <blockquote><span class="icon-blockquote"></span> <h4>dhassen</h4> <p></p> <p>&nbsp;I don't understand how you use the code you posted - where do you type that? Also, can someone translate to VB please?<br> </p> <p></p> </blockquote> &nbsp; <p></p> <p>&nbsp;</p> <p>Here You go:</p> <p>&nbsp;</p> <pre class="prettyprint">Private Shared Function FindControlIterative(ByVal root As Control, _ ByVal id As String) As Control Dim ctl As Control = root Dim ctls As LinkedList(Of Control) = New LinkedList(Of Control) Do While (ctl IsNot Nothing) If ctl.ID = id Then Return ctl End If For Each child As Control In ctl.Controls If child.ID = id Then Return child End If If child.HasControls() Then ctls.AddLast(child) End If Next ctl = ctls.First.Value ctls.Remove(ctl) Loop Return Nothing End Function</pre> <p>&nbsp; Make sure you add:</p> <p>&nbsp;</p> <p>Imports System.Collections.Generic at the top of your code.</p> <p>&nbsp;</p> <p>&nbsp;</p> 2007-10-16T12:21:08-04:001999706http://forums.asp.net/p/1107107/1999706.aspx/1?Re+Solution+to+the+FindControl+problemRe: Solution to the FindControl problem <p>i think using of findcontrol() on your formview or anyother control name, it&nbsp;is the best way as you neednot to actually go down on your performance and also you can get rid of all the code that has been shown on the top and one which make full use of the api's and its functions which microsoft provides.</p> 2007-11-10T14:02:59-05:001999748http://forums.asp.net/p/1107107/1999748.aspx/1?Re+Solution+to+the+FindControl+problemRe: Solution to the FindControl problem <p></p> <blockquote><span class="icon-blockquote"></span> <h4>chalamarc</h4> <p></p> <p>i think using of findcontrol() on your formview or anyother control name, it&nbsp;is the best way as you neednot to actually go down on your performance and also you can get rid of all the code that has been shown on the top and one which make full use of the api's and its functions which microsoft provides.</p> <p></p> </blockquote> &nbsp; <p></p> <p>If that were a valid argument, we would still be coding in COBOL and FORTRAN, or maybe 1s and 0s. :)&nbsp;</p> <p>Computer Science is the science of giving away something you want to get something else you want more.</p> <p>Which route to use is simply a matter of priorities.&nbsp; The recursive (or iterative) versions of FindControl provide the following benefits and drawbacks:</p> <p>-&nbsp; Runtime Performance<br> &#43; Codetime Performance (it's faster and more convenient for the programmer!)<br> &#43; Robustness when the number of levels in the UI Layer changes<br> &#43; Easier code to read.<br> </p> <p>Hard-wiring the reference by nesting chaining FindControl methods offers the following benefits and drawbacks:</p> <p>&#43; Runtime Performance<br> -&nbsp; Codetime Performance <br> -&nbsp; Robustness<br> -&nbsp; Harder to read.</p> <p>Pick the method that best meets your needs.<br> <br> &nbsp;</p> 2007-11-10T15:28:06-05:002006522http://forums.asp.net/p/1107107/2006522.aspx/1?Re+Solution+to+the+FindControl+problemRe: Solution to the FindControl problem <p>I am new to ASP.net and I would like to know how you would actually use the above method. Could you please give an example?</p> <p>Thanks.</p> 2007-11-14T17:50:24-05:002017584http://forums.asp.net/p/1107107/2017584.aspx/1?Re+Solution+to+the+FindControl+problemRe: Solution to the FindControl problem <p>I receive this error message while trying to run this procedure: &quot;The type or namespace name 'Generic' does not exist in the class or namespace 'System.Collections' (are you missing an assembly reference?)&quot;</p> <p>&nbsp;</p> 2007-11-20T23:32:09-05:002072832http://forums.asp.net/p/1107107/2072832.aspx/1?Re+Solution+to+the+FindControl+problemRe: Solution to the FindControl problem <p>I get a null reference exception for this line:</p> <p>&nbsp;ctl = ctls.First.Value;</p> <p>&nbsp;When I try to use that code. Any ideas why? Thanks.<br> &nbsp;</p> 2007-12-21T15:41:09-05:002073392http://forums.asp.net/p/1107107/2073392.aspx/1?Re+Solution+to+the+FindControl+problemRe: Solution to the FindControl problem <p>I've been through something similar a few times myself so I can probably help you. Before I try that, however, please give me the following information so I can customize an answer to your question:</p> <p>(1) VB or C#?&nbsp;&nbsp; (2) The code for your control and what you want to find.</p> 2007-12-21T21:40:14-05:002112340http://forums.asp.net/p/1107107/2112340.aspx/1?Re+Solution+to+the+FindControl+problemRe: Solution to the FindControl problem <p>good job</p> <p>&nbsp;</p> <p>&nbsp;</p> 2008-01-16T08:39:19-05:002197067http://forums.asp.net/p/1107107/2197067.aspx/1?Re+Solution+to+the+FindControl+problemRe: Solution to the FindControl problem <p>A couple more variations that may help you.&nbsp; They both use generics to return a specific type of control.</p> <p>&nbsp;</p> <font color="#008000" size="2"><pre class="prettyprint">'Find first instance of a control: Private Shared Function FindControlIterative(Of T As Control)(ByVal root As Control, ByVal id As String) As T Dim ctl As Control = root Dim ctls As LinkedList(Of Control) = New LinkedList(Of Control) Do While (ctl IsNot Nothing) If ctl.ID = id Then Return ctl End If For Each child As Control In ctl.Controls If child.ID = id Then Return child End If If child.HasControls() Then ctls.AddLast(child) End If Next ctl = ctls.First.Value ctls.Remove(ctl) Loop Return Nothing End Function 'Build collection of controls with matching ID (useful if root is a GridView control for example): Private Shared Function FindControlCollection(Of T As Control)(ByVal root As Control, ByVal id As String) As List(Of T) Dim ctl As Control = root Dim ctls As LinkedList(Of Control) = New LinkedList(Of Control) Dim ControlCollection As New List(Of T) Do While (ctl IsNot Nothing) If ctl.ID = id Then ControlCollection.Add(ctl) End If For Each child As Control In ctl.Controls If child.ID = id Then ControlCollection.Add(child) End If If child.HasControls() Then ctls.AddLast(child) End If Next If (ctls.Count &gt; 0) Then ctl = ctls.First.Value ctls.Remove(ctl) Else ctl = Nothing End If Loop Return ControlCollection End Function</pre>&nbsp;</font><font color="#0000ff" size="2"></font> 2008-02-26T17:41:50-05:002197708http://forums.asp.net/p/1107107/2197708.aspx/1?Re+Solution+to+the+FindControl+problemRe: Solution to the FindControl problem <p>Could you please provide a C# version of the code since I am not familiar with VB?</p> <p>Thanks.</p> 2008-02-27T00:44:45-05:00