2010-12-02 34 views
6

c'est un exemple de code de mon contrôle serveur personnalisé:Databinding sur le contrôle personnalisé avec ITemplate

[Designer(typeof(ContainerControlDesigner))] 
[ToolboxData("<{0}:BlocArrondi runat=server><ContenuPrincipal></ContenuPrincipal></{0}:BlocArrondi>")] 
public class BlocArrondi : WebControl 
{ 
    private ITemplate _ContenuPrincipal; 
    protected Panel _PanelContenuPrincipal = new Panel(); 

    public BlocArrondi() 
    : base(HtmlTextWriterTag.Div) 
    { 

    } 

    [PersistenceMode(PersistenceMode.InnerProperty)] 
    [TemplateInstance(TemplateInstance.Single)] 
    public ITemplate ContenuPrincipal 
    { 
      get { return _ContenuPrincipal; } 
      set { _ContenuPrincipal = value; } 
    } 

    protected override void OnInit(EventArgs e) 
    { 
      base.OnInit(e); 
      _PanelContenuPrincipal.ID = "PanelPrincipal"; 
      this.Controls.Add(_PanelContenuPrincipal); 

      if (_ContenuPrincipal != null) 
        _ContenuPrincipal.InstantiateIn(_PanelContenuPrincipal); 
    } 
} 

et ici la mise en œuvre:

<controls:BlocArrondi runat="server"> 
    <ContenuPrincipal> 
     <asp:Label id="LabelInfo" runat="server" /> 
    </ContenuPrincipal> 
</controls:BlocArrondi> 

Mon étiquette LabelInfo est accessible sur le code derrière, grand !

Mais si j'utiliser mon contrôle personnalisé dans un répéteur ou un ListView, je ne peux pas utiliser la propriété Container.DataItem à l'intérieur du modèle ContenuPrincipal:

<asp:Repeater id="RepeaterInfos" runat="server"> 
    <ItemTemplate> 
     <controls:BlocArrondi runat="server"> 
      <ContenuPrincipal> 
       <asp:Label runat="server" Text="<%# (Container.DataItem as MsgInfo).DisplayMessage() " /> 
      </ContenuPrincipal> 
     </controls:BlocArrondi> 
    </ItemTemplate> 
</asp:Repeater> 

Le message d'erreur:

'System.Web.UI.Control' ne contient pas de définition pour 'DataItem' et aucune méthode d'extension 'DataItem' acceptant un premier argument de type 'System.Web.UI.Control' n'a été trouvée (il manque une directive using ou une référence d'assemblage?)

Comment puis-je utiliser la propriété Container.DataItem dans le modèle ContenuPrincipal de mon contrôle?

Répondre

4

Je résolu mon problème avec une coutume TemplateContainer hériter de IDataItemContainer:

public class BlocArrondiContainer : Panel, IDataItemContainer 

Change:

protected Panel _PanelContenuPrincipal = new Panel(); 

    [PersistenceMode(PersistenceMode.InnerProperty)] 
    [TemplateInstance(TemplateInstance.Single)] 
    public ITemplate ContenuPrincipal 
    { 
     get { return _ContenuPrincipal; } 
     set { _ContenuPrincipal = value; } 
    } 

Par:

protected BlocArrondiContainer _PanelContenuPrincipal = new BlocArrondiContainer(); 

    [PersistenceMode(PersistenceMode.InnerProperty)] 
    [TemplateInstance(TemplateInstance.Single)] 
    [TemplateContainer(typeof(BlocArrondiContainer))] 
    public ITemplate ContenuPrincipal 
    { 
     get { return _ContenuPrincipal; } 
     set { _ContenuPrincipal = value; } 
    } 

Overrinding la méthode OnDataBinding sur la classe BlocArrondi:

protected override void OnDataBinding(System.EventArgs e) 
    { 
     if (NamingContainer is IDataItemContainer) 
      _PanelContenuPrincipal.DataItem = (NamingContainer as IDataItemContainer).DataItem; 

     base.OnDataBinding(e); 
    } 
+0

Excellente solution à votre problème. Je venais à presque la même chose. –