2009-04-08 20 views
8

मेरे पास एक मास्टर पेज है जो 2 स्तरों को घोंसला है। इसमें एक मास्टर पेज है, और उस मास्टर पेज का मास्टर पेज है।नेस्टेड मास्टर पेजों के अंदर नियंत्रण ढूंढना

जब मैं नाम "बीसीआर" के साथ एक ContentPlaceHolder में नियंत्रण छड़ी - मैं बहुत तरह नियंत्रण ढूंढने के लिए है:

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

मैं पूरी तरह खो दिया है? या यह कैसे किया जाना चाहिए?

मैं एक मल्टीव्यू के साथ काम करने वाला हूं, जो एक सशर्त सामग्री नियंत्रण के अंदर है। तो अगर मैं दृश्य को बदलना चाहता हूं तो मुझे उस नियंत्रण का संदर्भ प्राप्त करना होगा? उस संदर्भ को प्राप्त करना भी नास्टियर होने जा रहा है! क्या कोई बेहतर तरीका है?

धन्यवाद

उत्तर

4

सबसे पहले, आपको पता होना चाहिए कि MasterPages वास्तव में पेज के अंदर बैठते हैं। इतना है कि एक मास्टरपेज लोड इवेंट वास्तव में आपके एएसपीएक्स लोड इवेंट के बाद बुलाया जाता है।

इसका मतलब है, पेज ऑब्जेक्ट वास्तव में नियंत्रण पदानुक्रम में उच्चतम नियंत्रण है।

तो, यह जानकर, इस तरह के घोंसले वाले वातावरण में किसी भी नियंत्रण को खोजने का सबसे अच्छा तरीका, एक पुनरावर्ती कार्य लिखना है जो हर नियंत्रण और बाल नियंत्रण के माध्यम से लूप करता है जब तक कि वह आपको ढूंढ न सके। इस मामले में, आपके मास्टरपेज वास्तव में मुख्य पृष्ठ नियंत्रण के बाल नियंत्रण हैं।

आप इस तरह का कोई नियंत्रण अंदर से मुख्य पृष्ठ वस्तु को पाने:

सी #:

this.Page;

VB.NET

Me.Page

मुझे लगता है कि आम तौर पर नियंत्रण की क्लास FindControl() विधि, सुंदर बेकार है के रूप में पर्यावरण हमेशा नीडिंत है।

क्योंकि यदि यह है, तो मैंने नियंत्रण कक्षा का विस्तार करने के लिए .NET की 3.5 नई एक्सटेंशन सुविधाओं का उपयोग करने का निर्णय लिया है।

, कोड के नीचे (VB.NET) का उपयोग कर कहते हैं में, अपने AppCode फ़ोल्डर से, आपके सभी नियंत्रण अब FindByControlID को फोन करके एक पुनरावर्ती खोज peform जाएगा()

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 
22

ढूँढना नियंत्रण एक दर्द है, और मैं इस विधि है जो मैं काफी कुछ समय पहले CodingHorror blog से मिला उपयोग कर रहे हैं, एक भी संशोधन है कि रिक्त रिटर्न एक खाली आईडी में पारित हो जाता है, तो साथ।

/// <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"); 

इस विधि का उपयोग आम तौर पर अधिक सुविधाजनक है, क्योंकि आपको यह जानने की आवश्यकता नहीं है कि नियंत्रण कहां रहता है (मान लीजिए कि आप आईडी को जानते हैं), यद्यपि यदि आपके पास घोंसला नियंत्रण है वही नाम, आपको शायद कुछ अजीब व्यवहार मिलेगा, ताकि यह देखने के लिए कुछ हो।

+0

यह पूरी तरह से काम करता है। धन्यवाद। –

+0

+1 धन्यवाद यह मुझे – leen3o

+0

+1 में भी मदद करता है मुझे पता है कि यह 5 साल की तरह है, लेकिन इस विधि ने मुझे कुछ सिरदर्द बचाया, धन्यवाद! – psoshmo

4

हालांकि मुझे रिकर्सन पसंद है, और एंडी और मुन के साथ सहमत हैं, एक अन्य दृष्टिकोण जिसे आप विचार करना चाहते हैं, strongly typed Master page है। आपको बस इतना करना है कि अपने एएसपीएक्स पेज में एक निर्देश जोड़ें।

अपने मास्टर पेज से किसी पृष्ठ के नियंत्रण तक पहुंचने के बजाय, पृष्ठ से अपने मास्टर पेज में नियंत्रण तक पहुंचने पर विचार करें। जब आपके मास्टर पेज पर हेडर लेबल होता है तो यह दृष्टिकोण बहुत समझ में आता है, और मास्टर का उपयोग करने वाले प्रत्येक पृष्ठ से अपना मान सेट करना चाहता है।

मैं 100% निश्चित नहीं हूं, लेकिन मुझे लगता है कि यह नेस्टेड मास्टर पेजों के साथ सरल तकनीक होगी, क्योंकि आप उस वर्चुअलपैथ को उस मास्टर पर इंगित करेंगे जिसमें आप जिस नियंत्रण को एक्सेस करना चाहते हैं। यह मुश्किल हो सकता है हालांकि यदि आप दो नियंत्रणों तक पहुंचना चाहते हैं, तो प्रत्येक संबंधित मास्टर पेज में से एक।

+0

हाँ, अच्छा बिंदु। कभी-कभी यह आपके कस्टम पेज बेस में किसी प्रकार की विधि या संपत्ति में उस कार्यक्षमता को रखने के लिए अच्छा होता है। हालांकि, यह रिकर्सिव कंट्रोल फाइंडर्स में निर्मित होने से कोई दिक्कत नहीं करता है – andy

1

मैंने <%@ 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; 
     } 

    } 

इम समान व्यवहार बनाने के लिए विस्तार से गुरु से मुख्य मास्टर संपत्ति बुला है।

0

मुझे अभी यह पूरी तरह से काम कर रहा है। (है कि एक लैम्ब्डा अभिव्यक्ति हो सकती है!)

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

2

यहाँ एक कोड है कि अधिक सामान्य है और एक कस्टम शर्त के साथ काम करता है:

contentpage.aspx में, मैं निम्नलिखित लिखा था कॉल करें:

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; 
    } 
} 
संबंधित मुद्दे