[英]C#: Get all the controls with runat=“server”
I have a lot of .aspx pages with a lot of controls. 我有很多带有很多控件的.aspx页面。 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" .
我想知道是否有一种方法可以使用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 得到它们,但是我在调试模式下查看了myControls ,它似乎得到了少量控件,也许只有用asp特定符号声明的控件 , 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. 使用上述列表,我只需执行一个foreach循环,并用几行代码向每个属性添加readonly属性。 Ideas?
有想法吗? (Or maybe I'm just dumb and wasn't able to navigate and search trough myControls in the right way =D )
(或者也许我只是笨蛋,无法以正确的方式导航和搜索myControls = D)
Taken from: Get All Web Controls of a Specific Type on a Page 摘自: 在页面上获取特定类型的所有Web控件
/// <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");
}
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)
并通过放置
whatYouWannaDo(Page.Controls)
调用
Apologies for VB.NET. 为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):
您还需要从nuget中获取IEnumerable上的Each扩展方法(尝试使用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(). 这使您可以调用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.
在这种情况下,将控件包装在(或使用Panel)中,然后在其上调用SetInputControlsToReadonly。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.