簡體   English   中英

具有兩個模板的模板化用戶控件,如何在其他模板中查找需要控件ID的屬性的控件

[英]Templated User Control with two templates how to find control in other template for properties which require control id

我有一個帶有兩個模板的模板化用戶控件,並且一切正常,除了為另一個模板中存在的控件設置了諸如AssociatedControlID或ControlToValidate之類的ID之外。

我知道它們存在於兩個不同的命名容器中,這阻止了它們彼此查找,因此在下面的代碼中,設置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>

編輯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();
}

這是所有擴展方法:

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;

至於Label的AssociatedControlID,我還沒有弄清楚。

祝你好運,

肖恩

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM