簡體   English   中英

在嵌套母版頁中查找控件

[英]Finding controls inside nested master pages

我有一個嵌套2級的母版頁。 它有一個母版頁,該母版頁有一個母版頁。

當我在名為“bcr”的ContentPlaceHolder中粘貼控件時 - 我必須找到如下所示的控件:

 Label lblName =(Label)Master.Master.FindControl("bcr").FindControl("bcr").FindControl("Conditional1").FindControl("ctl03").FindControl("lblName");

我完全失去了嗎? 或者這是它需要做的?

我即將使用MultiView,它位於條件內容控件中。 所以,如果我想要更改視圖,我必須獲得對該控件的引用嗎? 得到這個參考將更加骯臟! 有沒有更好的辦法?

謝謝

找到控件是一件痛苦的事情,我一直在使用這種方法,這是我很久以前從CodingHorror博客中獲得的,只有一個修改,如果傳入一個空id,則返回null。

/// <summary>
/// Recursive FindControl method, to search a control and all child
/// controls for a control with the specified ID.
/// </summary>
/// <returns>Control if found or null</returns>
public static Control FindControlRecursive(Control root, string id)
{
    if (id == string.Empty)
        return null;

    if (root.ID == id)
        return root;

    foreach (Control c in root.Controls)
    {
        Control t = FindControlRecursive(c, id);
        if (t != null)
        {
            return t;
        }
    }
    return null;
}

在您的情況下,我認為您需要以下內容:

Label lblName = (Label) FindControlRecursive(Page, "lblName");

使用此方法通常更方便,因為您不需要確切知道控件所在的位置(當然,假設您知道ID),但如果您使用相同名稱的嵌套控件,則會可能會有一些奇怪的行為,所以這可能需要注意。

首先,您應該知道MasterPages實際上位於Pages中。 因此,在ASPX的Load事件之后實際調用MasterPage的Load事件。

這意味着,Page對象實際上是控件層次結構中的最高控件。

因此,了解這一點,在這樣的嵌套環境中找到任何控件的最佳方法是編寫一個遞歸函數,循環遍歷每個控件和子控件,直到找到您正在查找的控件。 在這種情況下,您的MasterPages實際上是主頁面控件的子控件。

您可以從任何控件內部訪問主Page對象,如下所示:

C#:

這一頁;

VB.NET

Me.Page

我發現通常,Control的類FindControl()方法是無用的,因為環境總是嵌套的。

因為如果這樣,我決定使用.NET的3.5新擴展功能來擴展Control類。

通過使用下面的代碼(VB.NET),比如你的AppCode文件夾,所有的控件現在都可以通過調用FindByControlID()來執行遞歸查找

    Public Module ControlExtensions
    <System.Runtime.CompilerServices.Extension()> _
    Public Function FindControlByID(ByRef SourceControl As Control, ByRef ControlID As String) As Control
        If Not String.IsNullOrEmpty(ControlID) Then
            Return FindControlHelper(Of Control)(SourceControl.Controls, ControlID)
        Else
            Return Nothing
        End If
    End Function

    Private Function FindControlHelper(Of GenericControlType)(ByVal ConCol As ControlCollection, ByRef ControlID As String) As Control
        Dim RetControl As Control

        For Each Con As Control In ConCol
            If ControlID IsNot Nothing Then
                If Con.ID = ControlID Then
                    Return Con
                End If
            Else
                If TypeOf Con Is GenericControlType Then
                    Return Con
                End If
            End If

            If Con.HasControls Then
                If ControlID IsNot Nothing Then
                    RetControl = FindControlByID(Con, ControlID)
                Else
                    RetControl = FindControlByType(Of GenericControlType)(Con)
                End If

                If RetControl IsNot Nothing Then
                    Return RetControl
                End If
            End If
        Next

        Return Nothing
    End Function

End Module

雖然我喜歡遞歸,並且同意andy和Mun,但您可能需要考慮的另一種方法是使用強類型的母版頁 您所要做的就是在aspx頁面中添加一個指令。

不要從主頁面訪問頁面控件,而是考慮從頁面本身訪問主頁面中的控件。 當您在母版頁上有標題標簽並希望從使用母版的每個頁面設置其值時,這種方法很有意義。

我不是百分百肯定,但我認為這對於嵌套母版頁來說會更簡單,因為你只需將VirtualPath指向包含你想要訪問的控件的master。 如果你想訪問兩個控件,每個相應的母版頁中有一個控件,它可能會很棘手。

這是一個更通用的代碼,可以使用自定義條件(可以是lambda表達式!)

呼叫:

Control founded = parent.FindControl(c => c.ID == "youdId", true);

控制擴展

 public static class ControlExtensions
{
    public static Control FindControl(this Control parent, Func<Control, bool> condition, bool recurse)
    {
        Control founded = null;
        Func<Control, bool> search = null;
        search = c => c != parent && condition(c) ? (founded = c) != null :
                                                    recurse ? c.Controls.FirstOrDefault(search) != null :
                                                    (founded = c.Controls.FirstOrDefault(condition)) != null;
        search(parent);
        return founded;
    }
}

我使用了<%@ MasterType VirtualPath="~/MyMaster.master" %>方法。 我在主母版頁中有一個屬性,然后在詳細母版頁中有一個同名的屬性調用主母版屬性,它工作正常。

我在主母版頁中有這個

 public string MensajeErrorString
    {
        set
        {
            if (value != string.Empty)
            {
                MensajeError.Visible = true;
                MensajeError.InnerHtml = value;
            }
            else
                MensajeError.Visible = false;
        }


    }

這只是一個必須顯示錯誤消息的div元素。 我想在具有詳細母版頁的頁面中使用相同的屬性(這與主母版嵌套)。

然后在細節大師我有這個

  public string MensajeErrorString
    {
        set
        {
                Master.MensajeErrorString = value;
        }

    }

我從細節主機調用主要主屬性來創建相同的行為。

我剛剛完美地完成了它。

在contentpage.aspx中,我寫了以下內容:

If Master.Master.connectsession.IsConnected Then my coded comes in here End If

暫無
暫無

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

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