2011-10-05 24 views
5

पर उपयोगकर्ता नियंत्रण जोड़ना मेरे पास एक वर्ग (MyClass) है जो एक नेस्टेड पदानुक्रम का प्रतिनिधित्व करता है, इसलिए कक्षा में एक संपत्ति है जो MyClass का संग्रह है। MyClass में शीर्षक शीर्षकगतिशील रूप से दोहराना

इसे किसी वेब पेज पर दिखाने के लिए, मैं एक उपयोगकर्ता नियंत्रण बनाने की उम्मीद कर रहा था जिसमें दोहराना था। आइटम टेम्पलेट में मुझे शीर्षक संपत्ति प्रदर्शित करने के लिए शाब्दिक होगा, और पुनरावर्तक की आइटमक्रेटेड घटना पर, मैं उपयोगकर्ता नियंत्रण का एक नया उदाहरण तैयार करूंगा, और इसे दोहराने वाले वर्तमान आइटम में जोड़ दूंगा।

मेरी समस्या यह है कि जब उपयोगकर्ता नियंत्रण में पेज_लोड ईवेंट चला जाता है, यदि नियंत्रण गतिशील रूप से जोड़ा गया था, तो repMyClass repeater poroperty शून्य है, भले ही मैं EnsureChildControls को कॉल करता हूं। क्या मुझसे कोई चूक हो रही है? यदि मैं दोहराना बना देता हूं और आइटम टेम्पलेट में अपना userctonrol ड्रॉप करता हूं तो यह ठीक काम करता है। मैं इसे गतिशील रूप से काम करने के लिए नहीं मिल सकता?

उपयोगकर्ता नियंत्रण:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MyControl.ascx.cs" Inherits="MyControl" %> 
Items:<br/> 
<asp:Repeater ID="repMyClass" runat="server" EnableViewState="false" 
    OnItemCreated="repMenuItems_ItemCreated"> 
    <HeaderTemplate><ul><HeaderTemplate> 
    <ItemTemplate> 
     <li><%# Eval("Title") %> 
      <div><asp:PlaceHolder ID="SubItemPlaceholder" runat="server" /></div> 
     </li></ItemTemplate> 
    <FooterTemplate></ul></FooterTemplate> 
</asp:Repeater> 

उपयोगकर्ता नियंत्रण कोड:

public partial class MyControl: System.Web.UI.UserControl 
{ 
    public IEnumerable<MyClass> ChildItems { get; set; } 
    protected void Page_Load(object sender, EventArgs e) 
    { 
     this.repMyClass.DataSource = ChildItems; 
     this.repMyClass.DataBind(); 
    } 

    protected void repMenuItems_ItemCreated(object Sender, RepeaterItemEventArgs e) 
    { 
     if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item) 
     { 
      //Get the MyClass instance for this repeater item 
      MyClass mcCurrent = (MyClass)e.Item.DataItem; 

      //If the MyClass instance has child instances 
      if (mcCurrent.Children != null && mcCurrent.Children.Length > 0) 
      { 
       //Add a new user control and set it's property so it can bind 
       PlaceHolder ph = (PlaceHolder)e.Item.FindControl("SubItemPlaceholder"); 

       MyControl ctl = (MyControl)Page.LoadControl(typeof(MyControl),new object[] {}); 

       ctl.ChildItems = mcCurrent.Children; 
       ph.Controls.Add(ctl); 
      } 
     } 
    } 
} 
+0

क्या आप इसे समझाने और इसे साफ़ करने के लिए संपादित कर सकते हैं। मुझे लगता है कि शायद इस वाक्य में आपके पास आधा संपादन हो गया है जो पूरा नहीं हुआ? "मेरी समस्या यह है कि जब पृष्ठ-लोड ईवेंट पहले नियंत्रण के लिए पहले किया गया था, तो repNyClass repeater poroperty शून्य है" – chrismay

उत्तर

0

आप नियंत्रण है कि संपत्ति आप चाहते हैं और लोड घटना में इसका इस्तेमाल लेता है में एक और निर्माता बना सकते हैं, और उसके बाद से पारित यह वर्तमान में LoadControl() कॉल में खाली ऑब्जेक्ट सरणी में है।

एक और तरीका नियंत्रण की लोड घटना की बजाय संपत्ति के सेटटर में तर्क को आग लगाना है, क्योंकि अनिवार्य रूप से यहां वास्तविक भार है और यदि मैं इसे सही मानता हूं तो प्रति नियंत्रण प्रति अनुरोध पर आग लग जाती है।

एक अन्य दृष्टिकोण यह गतिशील रूप से लोड नहीं करना है।

अपने मद टेम्पलेट के अंदर आप की तरह कुछ हो सकता है:

<uc:MyControl runat="server 
    ChildItems='<%# ((MyClass) Container.DataItem).Children %>' 
    Visible='<%# ((MyClass) Container.DataItem).Children.Length > 0 %>' 
    /> 

अद्यतन

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

दरअसल, जब मैं इसके बारे में सोचता हूं, तो आपका कोड ऐसा नहीं होना चाहिए क्योंकि e.Item.DataItem अभी तक बाध्य नहीं है।

ईवेंट को आइटमडेटाबाउंड में बदलने का प्रयास करें और देखें कि यह काम करता है या नहीं।

मैं अभी भी सलाह देता हूं कि आप आइटम मार्कअप में नियंत्रण शामिल करें, और ईवेंट में नियंत्रण की दृश्यता को नियंत्रित करें (अब आइटमडेटाबाउंड होने के लिए)। आप e.Item.FindControl("ControlId") as MyControl जैसे कुछ द्वारा नियंत्रण का संदर्भ ले सकते हैं (यदि वर्तमान आइटम में नहीं मिला तो शून्य वापस आ जाएगा)।

दोनों के संयोजन का प्रयास करें, या कम से कम बनाया के बजाय बाध्य आंकड़ों के घटना में परिवर्तन, और आइए देखते हैं ...

+0

समस्या यह है कि, मेरे उपयोगकर्ता नियंत्रण में इसका अपना बाल नियंत्रण होता है (इस मामले में दोहराना)। उपयोगकर्ता नियंत्रण के पेज_लोड ईवेंट में, पुनरावर्तक चर वास्तव में शून्य है। मैं इसे स्वयं सेट नहीं कर सकता, एएसपीनेट ढांचे की जरूरत है। – Jeremy

+0

सिद्धांत यह है कि आपको लोड का उपयोग करने की आवश्यकता नहीं है, इसके बजाय सेटटर का उपयोग करें। एक और विकल्प उत्तर अद्यतन में है, कि कोई इस मुद्दे को ठीक कर सकता है। मुझे लगता है कि समस्या यह घटना है, इस मुद्दे के बारे में बहुत अच्छी संभावना है। – Meligy

3

मैं Accordions का उपयोग कर नेस्टेड रिपोर्ट बनाने के लिए एक लंबे समय पहले किया था।

सूचकांक, जब आप गतिशील रूप से उपयोगकर्ता नियंत्रण उदाहरणों जोड़ना चाहते हैं में:

// Declare Placeholder  
PlaceHolder ph = (PlaceHolder)e.Item.FindControl("SubItemPlaceholder") 

// Adding some literal controls to header 
ph.Controls.Add(new LiteralControl("This is the accordion header!!")); 

// Declare new control variable 
crt = new Control(); 

// Load up your User Control 
crt = LoadControl("~/MyControl.ascx"); 

// Check if it has loaded properly 
if (crt != null) 
{ 
    // GET/SET any custom properties of the User Control 
    ((myClass)crt).title = "Welcome"; 

    // Add the new User Control to the placeholder's controls collection 
    ph.Controls.Add(crt); 
} 

नोट: उपयोगकर्ता नियंत्रण में, आप घोषणा टैग में "classname" जोड़ना होगा

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MyControl.ascx.cs" Inherits="myTest" ClassName="myClass" %> 

इसके अलावा, किसी भी गुण को आप गतिशील रूप से उदाहरण बनाते समय बेनकाब करना चाहते हैं, तो आप उन्हें निम्नानुसार घोषित करते हैं:

public string title { get; set; } 

तो अगर आप जब के लिए बनाने एक मूल्य के लिए बाध्य करना चाहते "repMyClass" आप इसे एक संपत्ति के रूप में स्थापित और आप जो भी मान programmaticaly यह करना चाहते हैं निर्दिष्ट कर सकते हैं।

+0

समस्या यह है कि, मेरे उपयोगकर्ता नियंत्रण में इसका अपना बाल नियंत्रण होता है (इस मामले में दोहराना)। उपयोगकर्ता नियंत्रण के पेज_लोड ईवेंट में, पुनरावर्तक चर वास्तव में शून्य है। मैं इसे स्वयं सेट नहीं कर सकता, एएसपीनेट ढांचे की जरूरत है। – Jeremy

+0

@ जेरेमी: निश्चित रूप से आप कर सकते हैं। बस प्रकार दोहराने की एक संपत्ति बनाएँ। इसके बाद आप इसे एक्सेस कर सकते हैं, इसे तुरंत चालू कर सकते हैं, जो कुछ भी आप चाहते हैं उसे करें। कृपया स्पष्ट करें - मेरे अनुसार आपके पास UserControl में एक सार्वजनिक संपत्ति होनी चाहिए, उपयोगकर्ता नियंत्रण के पेज लोड में आपको उस सार्वजनिक संपत्ति का उपयोग पुनरावर्तक को डेटा को बाध्य करने के लिए करना चाहिए। क्या वो सही है? –

संबंधित मुद्दे