具有两个模板的模板化用户控件如何在其他模板中查找需要控件id的属性的控件
本文关键字:控件 其他 id 属性 查找 用户 两个 | 更新日期: 2023-09-27 18:08:25
我有一个模板化的用户控件与两个模板,一切都工作,除了设置id的东西,如AssociatedControlID或ControlToValidate的控件存在于另一个模板。
我知道它们存在于两个不同的命名容器中,这阻止了它们找到彼此,所以在下面的代码中设置AssociatedControlID不只是与控件id一起工作。是否有一些技巧可以声明式地设置它,或者我必须使用FindControl并在后面的代码中设置它?
这是我的控件布局:
<uc1:Field ID="paramName" runat="server">
<LabelTemplate >
<asp:Label ID="lblName" AssociatedControlID="txtValue" runat="server" >Label Text:</asp:Label>
</LabelTemplate>
<InputTemplate>
<asp:TextBox ID="txtValue" runat="server" MaxLength="30"></asp:TextBox>
</InputTemplate>
</uc1:Field>
EDIT 1:我甚至不能让它在后面的代码中设置它。我尝试将AssociatedControlID设置为。id,。clientid,。uniqueid。我总是忘记哪个是必需的,所以我尝试了所有这些。我也试着从FindControl中找到控件。我能够从控件的父控件中找到它,但不是父控件的父控件。这很奇怪。
编辑2:我已经想出了一个部分解决方案。它不为AssociatedControlID工作,但它确实为ControlToValidate工作,这对我来说更重要。这里是解决方法:在容器类中,您必须重写FindControl,并使其指向两层。然后你需要做你自己的FindControl,因为我尝试了Parent.Parent.FindControl,它仍然没有找到控件,我不完全明白为什么,所以我有一个扩展方法来枚举控件集合中的所有控件。我也不知道为什么它不与AssociatedControlID标签工作。也许在内部它调用FindControl的方式不同
我仍然觉得我错过了一些简单的东西。
/// <summary>
/// This is a hack to get the validators in the label template to see the controls in the input template
/// just don't name any controls in the two templates the same thing
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public override Control FindControl(string id)
{
if (Parent == null && Parent.Parent == null)
{
return base.FindControl(id);
}
return Parent.Parent.Controls.All().Where(x => x.ID == id).FirstOrDefault();
}
下面是All扩展方法:
public static IEnumerable<Control> All(this ControlCollection controls)
{
foreach (Control control in controls)
{
foreach (Control grandChild in control.Controls.All())
yield return grandChild;
yield return control;
}
}
谢谢你帮我解决这个烦人的问题。
克里斯对于ControlToValidate,您可以在InputTemplate控件的类定义上使用ValidationPropertyAttribute。只需将代码更新为:
//"Text" is the name of the Property which returns the value to validate
[ValidationProperty("Text")]
public class InputTemplate
{
...
public string Text { set { txtValue.Text = value; } get { return txtValue.Text } }
}
现在在你的代码后面,你可以设置你的RequiredFieldValidator的ControlToValidate属性为用户控件的ID:如。RequiredFieldValidator1.ControlToValidate = InputTemplate1.ID;
至于标签的AssociatedControlID,我还没有弄清楚。
祝你好运,
肖恩