2011-10-05 28 views
5

İç içe geçmiş bir hiyerarşiyi temsil eden bir sınıfım (MyClass) var, dolayısıyla sınıfın bir MyClass koleksiyonu olan bir özelliği var. Sınıfım da ben bir Tekrarlayıcı vardı bir kullanıcı denetimi oluşturmak umuyordum, bir web sayfasında göstermek için bir başlık, tesisiTekrarlayıcıya kullanıcı denetimi dinamik olarak ekleme

sahiptir. Öğe şablonunda, title özelliğini görüntülemek tam anlamıyla olurdu ve tekrarlayıcının ItemCreated olayında, usercontrol'ün yeni bir örneğini oluşturabilir ve tekrarlayıcıdaki mevcut öğeye ekleyebilirim.

Sorunum, usercontrol uygulamasında Page_Load olayı harekete geçtiğinde, denetim dinamik olarak eklendiyse, EnsureChildControls çağırsam bile repMyClass repeater poroperty değeri sıfırdır. Burada bir şey mi eksik? Eğer bir tekrarlayıcı oluşturursam ve userctonrol'umu öğe şablonuna bıraksam iyi çalışır. Bunu dinamik olarak çalışamıyorum mu?

Kullanıcı Kontrolü:

<%@ 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> 

Kullanıcı Kontrol Kodu: İstediğiniz ve yük durumunda kullanmak özelliğini alır kontrolde başka yapıcı olun ve sonra geçebilir

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

Bunu açıklamak ve belki de temizlemek için bunu düzenleyebilir misiniz? Belki de bu cümlenin tamamlanmayan yarısını düzenlediniz galiba? "Sorunum, dinamik olarak eklenen kontroller için Page_Load olayı ilk defa, repNyClass repeater poroperty null" olduğunda – chrismay

cevap

0

LoadControl() çağrısında şu anda boş nesne dizisinde. Diğer bir yaklaşım, mantığın kontrolün Load olayı yerine, münferit sette ateşlemesini sağlamaktır, çünkü esasen gerçek yük buradadır ve eğer doğru olursa, her kontrol başına bir kere ateşlenir.

Diğer bir yaklaşım, tüm dinamik olarak yüklemek değil. Öğe şablonu içinde

gibi bir şey olabilir:

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

Güncelleme

, tekrarlayıcı veya sayfa yaşam döngüsü içindeki kullanıcı denetimleri bana çocuk kontrolleriyle hataları vermedim Bir daha yaklaşımdır

Oluşturulan Öğe yerine Öğe Veri Bağlantısı olayını kullanmak için Şimdi bunu düşünmek zaman e.Item.DataItem değişmedi çünkü

Aslında, kodunuz olmamalıdır; t henüz bağlı olarak.

Olayı ItemDataBound olarak değiştirmeyi deneyin ve bunun işe yarayıp yaramadığını öğrenin.

.

Hala olsa öğe işaretlemesinde kontrolünü kapsar tavsiye ve (ItemDataBound olmak şimdi) durumunda kontrolün görünürlüğünü kontrol. Denetime, e.Item.FindControl("ControlId") as MyControl gibi bir öğeye başvurabilirsiniz (mevcut öğede bulunmadığında null döndürecektir).

+0

Sorun şu ki, kullanıcı kontrolüm kendi çocuk denetimlerine sahip (bu durumda bir tekrarlayıcı). Kullanıcı kontrolünün page_load olayında, tekrarlayıcı değişkeni aslında boştur. Bunu kendim ayarlayamıyorum, asp.net çerçevesinin ihtiyacı var. – Jeremy

+0

Teori, yükü kullanmanız gerekmemesi ve bunun yerine setter'i kullanmanız gerektiğidir. Başka bir alternatif de cevap güncellemesinde, sorunun düzeltilebileceğidir. Problemin kullanılan olay olduğunu düşünüyorum, bu konu olmanın çok iyi bir olasılığı var. – Meligy

3

Ben akordeon kullanarak iç içe raporlar oluşturmak için çok uzun zaman önce bu yapmıştı ... hem birleştirerek deneyin veya en azından yerine yaratılan sınırı verilere olayı değiştirme ve görelim.dinamik Kullanıcı Kontrol örneklerini eklemek istediğiniz Index, içinde

:

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

Not: kullanıcı denetimi olarak , sen beyanı etiketinde "SınıfAdı" eklemelisiniz

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

Ayrıca, örnekleri dinamik olarak oluştururken açığa vurmak istediğiniz tüm özellikleri, aşağıdaki gibi bildirirsiniz:

Eğer "repMyClass" için oluştururken bir değeri zorlamak istiyorsanız, onu bir özellik olarak ayarlayabilirsiniz ve programlı olarak istediğiniz herhangi bir değeri atayabilirsiniz.

+0

Sorun şu ki, kullanıcı kontrolüm kendi çocuk denetimlerine sahip (bu durumda bir tekrarlayıcı). Kullanıcı kontrolünün page_load olayında, tekrarlayıcı değişkeni aslında boştur. Bunu kendim ayarlayamıyorum, asp.net çerçevesinin ihtiyacı var. – Jeremy

+0

@Jeremy: Elbette yapabilirsin. Sadece tip tekrarlayıcı özelliği oluşturun. Daha sonra ona erişebilir, anlık hale getirebilir, onunla ne yaparsan yapabilirsin. Lütfen açıklığa kavuşturalım - bana göre, UserControl'de, UserControl'ün Sayfasında, tekrarlayıcıya veri bağlamak için bu özel mülkü kullanmanız gerekir. Bu doğru mu? –

İlgili konular