Reputation: 889
I have a lot of .aspx pages with a lot of controls. These controls are all declared in a similar way:
<input type="text" runat="server" id="txtLatitude" />
Now I have to check who the user is and, if not allowed to make changes, make all these controls readonly. Normally i would do somethink like
txtLatitude.Attributes.Add("readonly", "readonly")
but it would take me forever to do that manually for each control in each page. I was wondering if there is a way to get a List or something of all the controls with runat="server". I tried using
ControlCollection myControls = Page.Controls
to get them, but I looked at myControls in debug mode and it seems to get a small number of controls, maybe only the controls declared with the asp specific notation , not sure about it.
With said List i would simply do a foreach cycle and add the readonly attribute to each, with a few lines of code. Ideas? (Or maybe I'm just dumb and wasn't able to navigate and search trough myControls in the right way =D )
Upvotes: 2
Views: 1779
Reputation: 4918
Apologies for VB.NET. I do this with some extension methods. You also need to pick up an Each extension method on IEnumerable from nuget (try MoreLinq):
''' <summary>
''' Returns the control and all descendants as a sequence
''' </summary>
<Extension>
Public Iterator Function AsEnumerable(control As Control) As IEnumerable(Of Control)
Dim queue = New Queue(Of Control)
queue.Enqueue(control)
Do While queue.Count <> 0
control = queue.Dequeue()
Yield control
For Each c As Control In control.Controls
queue.Enqueue(c)
Next
Loop
End Function
<Extension>
Public Sub SetInputControlsToReadonly(control As Control)
control.AsEnumerable().Each(Sub(c)
If TypeOf c Is TextBox Then DirectCast(c, TextBox).ReadOnly = True
If TypeOf c Is ListControl Then DirectCast(c, ListControl).Enabled = False
End Sub)
End Sub
This allows you to call control.SetInputControlsToReadonly(). Sometimes you don't want to set all controls to readonly, only a section on the page. In this case wrap the controls in a (or use a Panel), and call SetInputControlsToReadonly on that.
Upvotes: 0
Reputation: 4919
Add this function on your page:
void whatYouWannaDo (Control con)
{
foreach (Control c in con.Controls)
{
if (c.Controls.Count > 0)
whatYouWannaDo(c);
else
{
//Do stuff here
}
}
}
You can do whatever you want in this recursive function. and call this by putting whatYouWannaDo(Page.Controls)
Upvotes: 0
Reputation: 21487
Taken from: Get All Web Controls of a Specific Type on a Page
/// <summary>
/// Provide utilities methods related to <see cref="Control"/> objects
/// </summary>
public static class ControlUtilities
{
/// <summary>
/// Find the first ancestor of the selected control in the control tree
/// </summary>
/// <typeparam name="TControl">Type of the ancestor to look for</typeparam>
/// <param name="control">The control to look for its ancestors</param>
/// <returns>The first ancestor of the specified type, or null if no ancestor is found.</returns>
public static TControl FindAncestor<TControl>(this Control control) where TControl : Control
{
if (control == null) throw new ArgumentNullException("control");
Control parent = control;
do
{
parent = parent.Parent;
var candidate = parent as TControl;
if (candidate != null)
{
return candidate;
}
} while (parent != null);
return null;
}
/// <summary>
/// Finds all descendants of a certain type of the specified control.
/// </summary>
/// <typeparam name="TControl">The type of descendant controls to look for.</typeparam>
/// <param name="parent">The parent control where to look into.</param>
/// <returns>All corresponding descendants</returns>
public static IEnumerable<TControl> FindDescendants<TControl>(this Control parent) where TControl : Control
{
if (parent == null) throw new ArgumentNullException("control");
if (parent.HasControls())
{
foreach (Control childControl in parent.Controls)
{
var candidate = childControl as TControl;
if (candidate != null) yield return candidate;
foreach (var nextLevel in FindDescendants<TControl>(childControl))
{
yield return nextLevel;
}
}
}
}
}
Then do something like:
foreach(var ctrl in Page.FindDescendants<HtmlInputText>())
{
ctrl.Attributes.Add("readonly","readonly");
}
Upvotes: 1