Hi all!
I am trying to discover and place into a ControlCollection all the controls
on a web page that match a particular type or begin with a particular name.
To do this, I've written a function that will go through the
ControlCollection passed to it and add the controls that match the condition
to another ControlCollection, as shown:
private System.Web.UI.ControlCollection FindControls(string ControlName,
System.Web.UI.ControlCollection ControlSet)
{
System.Web.UI.ControlCollection retval = new
System.Web.UI.ControlCollection(new System.Web.UI.Control());
foreach (System.Web.UI.Control thing in ControlSet)
{
if (thing.ID != null)
if (thing.ID.StartsWith(ControlName))
retval.Add(thing);
if (thing.HasControls())
FindControls(ControlName, thing.Controls, ref
retval);
}
return retval;
}
private void FindControls(string ControlName,
System.Web.UI.ControlCollection ControlSet, ref
System.Web.UI.ControlCollection retval)
{
foreach (System.Web.UI.Control thing in ControlSet)
{
if (thing.ID != null)
if (thing.ID.StartsWith(ControlName))
retval.Add(thing);
if (thing.HasControls())
FindControls(ControlName, thing.Controls, ref
retval);
}
}
When I try running this, the following exception is thrown:
"The list that this enumerator is bound to has been modified. An enumerator
can only be used if the list doesn't change."
With a stack trace of:
[InvalidOperationException: The list that this enumerator is bound to has
been modified. An enumerator can only be used if the list doesn't change.]
System.Web.UI.ControlCollectionEnumerator.MoveNext() +112
cs.webcontrols.FindControls(String ControlName, ControlCollection
ControlSet, ControlCollection& retval) in
c:\inetpub\wwwroot\cs\webcontrols.cs:75
cs.webcontrols.FindControls(String ControlName, ControlCollection
ControlSet) in c:\inetpub\wwwroot\cs\webcontrols.cs:67
cs.webcontrols.Page_Load(Object sender, EventArgs e) in
c:\inetpub\wwwroot\cs\webcontrols.cs:28
System.EventHandler.Invoke(Object sender, EventArgs e) +0
System.Web.UI.Control.OnLoad(EventArgs e) +67
System.Web.UI.Control.LoadRecursive() +35
System.Web.UI.Page.ProcessRequestMain() +731
When I trace through, the error occurs when I hit the first match, do a
.Add, and loop around for the next control. So, I put more watches on the
variables around what .NET claimed was the offending line. I watched it run
through and found that when the .Add method was called, it didn't copy a
reference to the control as I would have expected...it MOVED the control
from the parent ControlCollection to the new ControlCollection.
So, I tried to fool .NET by adding a function:
private void addControl(System.Web.UI.Control inControl, ref
System.Web.UI.ControlCollection retval)
{
retval.Add(inControl);
}
and I change from calling .Add to:
addControl(thing, ref retval);
thinking that because I was passing copies, .NET wouldn't be able to modify
the original.
Wrong.
I ran the modified code and watched .NET do the same thing all over again.
So...what is going on?? It appears that System.Web.UI.ControlCollection(s)
passes a pointer and not a copy. To add to that, the only way to copy this
class is by calling the ".CopyTo" method which puts the control into a
System.Array. This doesn't seem right either.
I must be going about this the hard way. Anyone have any suggestions or
ideas?
TIA!
Jason Bryan