IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

ASP.NET Discussion :

Composite Control et évènements


Sujet :

ASP.NET

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    166
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2004
    Messages : 166
    Par défaut Composite Control et évènements
    J'ai construit un Custom Composite Control qui contient 2 Interface ITemplate:
    1. HeaderTemplate
    2. ContentTemplate


    Jusque là tous fonctionne bien: J'ai overrid" les méthodes suivantes:
    • CreateChildControls
    • Render
    • OnInit


    Et j'obtiens bien le comportement attendu: les contrôles ajoutés dans les Templates sont bien rendus.

    Par contre, si je place un Bouton dans un des Template, là je bloque:

    Le clic effectue bien un postback. Par contre, je n'arrive pas à intercepté cette évènement dans le code-behind pour effectuer mes traitements.

    Quelqu'un aurait des infos sur les évènements dans les CompositeControl et les Templates?


    Autre petite question annexe: Je souhaiterais avoir l'archiecture suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <cc1:MonControl...... >
      <HeaderTemplate>
        <Item Key="key1" Value="value1" Type="type1" />
        <Item Key="key2" Value="value2" Type="type2" />
        ....
        <Item Key="key3" Value="value3" Type="type3" />
      </HeaderTemplate>
      <ContentTemplate>
        <asp:Button ..... />
        ....
      </ContentTemplate>
    </cc1:MonControl>
    Comment faire pour avoir une liste d'item dans le HeaderTemplate

    merci

  2. #2
    Membre Expert
    Avatar de Pongten
    Homme Profil pro
    IT Analyst & Software Developer
    Inscrit en
    Juin 2002
    Messages
    1 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : IT Analyst & Software Developer
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 173
    Par défaut
    Pour répondre à ta première question, il faut que tous les contrôles soient reconstruits pour pouvoir capturer l'événement. Est-ce bien la cas ?

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    166
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2004
    Messages : 166
    Par défaut
    Dans le OnInit, j'appele EnsureChildControls().
    Si je ne me trompe pas, EnsureChildControls(), appelle CreateChildControls() si besoin non?

  4. #4
    Membre Expert
    Avatar de Pongten
    Homme Profil pro
    IT Analyst & Software Developer
    Inscrit en
    Juin 2002
    Messages
    1 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : IT Analyst & Software Developer
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 173
    Par défaut
    Oui.. en fait, j'ai parlé un peu vite.. est-ce que ton contrôle est ajouté dynamiquement à la page ?

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    166
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2004
    Messages : 166
    Par défaut
    Absolument pas

  6. #6
    Membre Expert
    Avatar de Pongten
    Homme Profil pro
    IT Analyst & Software Developer
    Inscrit en
    Juin 2002
    Messages
    1 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : IT Analyst & Software Developer
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 173
    Par défaut
    Est-ce que tu affectes manuellement un ID à ton bouton dans ton contrôle ?
    Si ce n'est pas le cas, tu devrais peut-être essayer...

  7. #7
    Membre éprouvé

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    68
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 68
    Par défaut Un contrôle avec Template
    Afin d'éviter de se perdre en conjecture, je crois qu'il serait très utile que la source du contrôle soit publiée.

    Le problème peut provenir de tout un ensemble de raisons, par exemple, si votre contrôle hérite de Control et non de WebControl, il ne supporte pas l'interface INamingContainer et les évènements ne fonctionneront pas comme vous l'attendez.

    Voici un exemple d'implémentation de votre situation à partir de System.Web.UI.Control.

    En prime, histoire de vous faire plaisir, j'ai implémenté un designer qui vous permettra de travailler en WYSIWYG avec votre contrôle. Histoire d'illustre la puissance de ASP.NET et de chatouillez l'imagination de chacun. Mais attention, si vous utilisez cette implémentation, sachez que la création de contrôles personnalisé peut vous amener sur des chemins périlleux.

    Code du contrôle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
     
     
    using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
     
    namespace Test
    {
    ///<summary>
    /// Item n‚cessaire … la collection Header
    ///</summary>
    publicclassItem
    {
    privatestring _Key = string.Empty;
    publicstring Key
    {
    get { return _Key; }
    set { _Key = value; }
    }
    privatestring _Value = string.Empty;
    publicstring Value
    {
    get { return _Value; }
    set { _Value = value; }
    }
    privatestring _Type = string.Empty;
    publicstring Type
    {
    get { return _Type; }
    set { _Type = value; }
    }
    }
    ///<summary>
    /// Collection d'item
    ///</summary>
    publicclassItemCollection : System.Collections.ObjectModel.Collection<Item>
    {
    }
    ///<summary>
    /// Control
    ///</summary>
    [System.ComponentModel.Designer(typeof(MyControlDesigner))] // R‚f‚rence au designer du contr“le (utilis‚ en mode design)
    [System.Web.UI.ParseChildren(true)] // Le contenu du control = propri‚t‚s
    [System.Web.UI.PersistChildren(false)] // Le contenu du contol != objects … placer dans la collection Controls
    publicclassMyControl : System.Web.UI.Control, INamingContainer
    {
    privateItemCollection _Header = newItemCollection();
    [System.Web.UI.PersistenceMode(PersistenceMode.InnerProperty)] // Cette propri‚t‚ persiste en tant que contenu (balise)
    [System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Content)] // On persiste le contenu de la collection
    publicItemCollection Header
    {
    get { return _Header; }
    // Il ne faut pas de set
    }
    privateITemplate _Content = null;
    [System.Web.UI.PersistenceMode(PersistenceMode.InnerProperty)] // Cette propri‚t‚ persiste en tant que contenu (balise)
    [System.Web.UI.TemplateInstance(TemplateInstance.Single)]
    publicITemplate Content
    {
    get { return _Content; }
    set { _Content = value; }
    }
    protectedoverridevoid CreateChildControls()
    {
    System.Web.UI.WebControls.Table tbl = newTable();
    this.Controls.Add(tbl);
    foreach (Item i in Header)
    {
    System.Web.UI.WebControls.TableRow rowHeader = newTableRow();
    tbl.Controls.Add(rowHeader);
    System.Web.UI.WebControls.TableCell cellHeader = newTableCell();
    cellHeader.Controls.Add(newLiteralControl("Key = "+i.Key+", Value = "+i.Value+", Type = "+i.Type));
    rowHeader.Controls.Add(cellHeader);
    }
    if (Content != null)
    {
    System.Web.UI.WebControls.TableRow rowContent = newTableRow();
    tbl.Controls.Add(rowContent);
    System.Web.UI.WebControls.TableCell cellContent = newTableCell();
    Content.InstantiateIn(cellContent);
    rowContent.Controls.Add(cellContent);
    if (DesignMode)
    {
    //---> Ce code aurait d'avantage sa place dans le designer, mais cela compliquerait
    // l'ensemble du code, je le place donc ici pour simplifier
    cellContent.Attributes.Add(System.Web.UI.Design.DesignerRegion.DesignerRegionAttributeName, "0");
    }
    }
    }
    publicoverridevoid RenderControl(HtmlTextWriter writer)
    {
    if (DesignMode)
    {
    //---> En mode design, beaucoup de changements peuvent intervenir en fonction
    // des int‚ractions utilisateur... Il faut donc recalculer tout le contr“le.
    Controls.Clear();
    CreateChildControls();
    }
    base.RenderControl(writer);
    }
    }
    ///<summary>
    /// Cette classe impl‚mente le designer du control. Utilis‚e en mode design. C'est cette classe
    /// qui d‚finie la r‚gion ‚ditable.
    ///</summary>
    publicclassMyControlDesigner : System.Web.UI.Design.ControlDesigner
    {
    privateconststring REGION_CONTENT = "Content";
    publicoverridestring GetDesignTimeHtml()
    {
    //---> Cette surchage est n‚cessaire car MyControl h‚rite de Control et non de WebControl
    // et que par d‚finition son rendu n'est pas effectu‚.
    System.IO.StringWriter sWriter = new System.IO.StringWriter();
    System.Web.UI.HtmlTextWriter tWriter = newHtml32TextWriter(sWriter);
    (this.Component asMyControl).RenderControl(tWriter);
    return sWriter.ToString();
    }
    publicoverridestring GetDesignTimeHtml(System.Web.UI.Design.DesignerRegionCollection regions)
    {
    //---> Nous d‚finissons une r‚gion
    regions.Add(new System.Web.UI.Design.EditableDesignerRegion(this, REGION_CONTENT));
    returnbase.GetDesignTimeHtml(regions);
    }
    publicoverridestring GetEditableDesignerRegionContent(System.Web.UI.Design.EditableDesignerRegion region)
    {
    if (region.Name == REGION_CONTENT)
    {
    //---> Le code HTML de la r‚gion est demand‚, on le fournit
    System.ComponentModel.Design.IDesignerHost host = this.GetService(typeof(System.ComponentModel.Design.IDesignerHost)) as System.ComponentModel.Design.IDesignerHost;
    return System.Web.UI.Design.ControlPersister.PersistTemplate((Component asMyControl).Content, host);
    }
    returnbase.GetEditableDesignerRegionContent(region);
    }
    publicoverridevoid SetEditableDesignerRegionContent(System.Web.UI.Design.EditableDesignerRegion region, string content)
    {
    if (region.Name == REGION_CONTENT)
    {
    //---> Un nouveau code HTML de la r‚gion est transmis, on met le Template … jour
    System.ComponentModel.Design.IDesignerHost host = this.GetService(typeof(System.ComponentModel.Design.IDesignerHost)) as System.ComponentModel.Design.IDesignerHost;
    (Component asMyControl).Content = System.Web.UI.Design.ControlParser.ParseTemplate(host, content);
    }
    base.SetEditableDesignerRegionContent(region, content);
    }
    }
    }
    Aspx :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <%@PageLanguage="C#"AutoEventWireup="true"CodeFile="Default.aspx.cs"Inherits="_Default" %>
    <%@RegisterTagPrefix="Test"Namespace="Test" %>
    <!DOCTYPEhtmlPUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <htmlxmlns="http://www.w3.org/1999/xhtml">
    <headrunat="server">
    <title>Page sans titre</title>
    </head>
    <body>
    <formid="form1"runat="server">
    <Test:MyControlid="ctrl"runat="server">
    <Header>
    <Test:ItemKey="Key1"Type="Type1"Value="Value1"/>
    <Test:ItemKey="Key2"Type="Type2"Value="Value2"/>
    <Test:ItemKey="Key3"Type="Type3"Value="Value3"/>
    </Header>
    <Content>
    <asp:TextBoxID="txt"runat="server"></asp:TextBox>
    <asp:Buttonid="bt"runat="server"Text="ok"OnClick="bt_Click"/>
    </Content></Test:MyControl>
    </form>
    </body>
    </html>
    Code de l'aspx :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    publicpartialclass_Default : System.Web.UI.Page
    {
    protectedvoid Page_Load(object sender, EventArgs e)
    {
    }
    protectedvoid bt_Click(object sender, EventArgs e)
    {
    txt.Text = "ok";
    }
    }
    Bon courage et bonne continuation.
    Fichiers attachés Fichiers attachés

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    166
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2004
    Messages : 166
    Par défaut
    Je n'ai pas encore essayé d'adapter votre code au mien. ce que je peux vous dire par contre, c'est que mon control hérite de CompositeControl et de IPostBackEventHandler.

    Merci pour votre code, je vais creuser ça dès que possible.

  9. #9
    Membre éprouvé

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    68
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 68
    Par défaut
    Ce n'est pas un soucis si votre contrôle hérite de CompositeControl. Je suis volontairement parti sur la base de Control car en fait l'implémentation que je vous ai transmise n'utilise aucune des propriétés supplémentaires disponibles sur le CompositeControl par exemple (comme Width, Height,...).

    Si vous préférez hériter de CompositeControl, il faut simplement modifier le designer. Ce dernier n'hérite plus de ControlDesigner mais de CompositeControlDesigner. Et dans ce cas, vous pouvez supprimer la surcharge de la méthode GetDesignTimeHtml() car le CompositeControl effectue déjà un rendu en mode design, donc pas besoin de l'impplémenter.

    Tenez moi au courant si cela répond à vos besoins.

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    166
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2004
    Messages : 166
    Par défaut
    J'ai commencé à adapter votre code au mien.
    Tous se passe bien lorsque je ne saisis pas d'Item dans le Header.
    par contre, dès que j'ajoute des objets Item dans l'aspx et que j'essaye de compiler et de lancer l'application, je reçois le message d'erreur suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Erreur	1	Le nom de type 'ItemCollection' n'existe pas dans le type 'DialogWindow.DialogWindow'	c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\test\d35a43f0\1be9bbb3\App_Web_visdo_1t.0.cs	294
    Je ne vois pas du tout d'où sort ce fichier, et quel est le problème.

  11. #11
    Membre éprouvé

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    68
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 68
    Par défaut
    Si vous ouvrez le projet que je vous ai transmis vous constaterez que l'ajout manuel d'item dans l'aspx ne pose pas de problème.

    Il me faudrait donc votre code pour répondre à votre question. Le code de la classe Item, le code de la classe ItemCollection et le code de l'implémentassions de la propriété de collection des items dans l'objet.

  12. #12
    Membre éprouvé

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    68
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 68
    Par défaut Conflit de noms
    Problématique

    Après avoir audité le code de Le-Cortex il apparait que le message précédent est causé par un conflit de noms.
    • Le namespace utilisé est DialogWindow
    • Le nom du contrôle est DialogWindow
    Le code de Le-Cortex ressemble à ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    namespace DialogWindow
    {
     
       public class Item
       {
          ...
       }
     
       public class ItemCollection : ...
       {
       }
     
       public class DialogWindow : ...
       {
          // Toute référence à DialogWindow à l'intérieur de
          // ce contrôle fait en fait référence à la classe et nom
          // au namespace
          Item i = new Item();
          // génère le message d'erreur précédent
       }
     
    }
    Solution 1

    Changer soit le namespace soit le nom du contrôle.

    Solution 2

    A l'intérieur du contrôle, utiliser la syntaxe suivante pour faire référence aux autres classes du namespace.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    global::DialogWindow.Item
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    global::DialogWindow.CollectionItem
    Par exemple, dans le cas du code précédent :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    namespace DialogWindow
    {
     
       public class Item
       {
          ...
       }
     
       public class ItemCollection : ...
       {
       }
     
       public class DialogWindow : ...
       {
          // Toute référence à DialogWindow à l'intérieur de
          // ce contrôle fait en fait référence à la classe et nom
          // au namespace
          global::DialogWindow.Item i = new global::DialogWindow.Item();
          // ne génère plus le message d'erreur précédent
       }
     
    }

Discussions similaires

  1. Création dynamique de controles avec évènement
    Par Crampignon dans le forum VB.NET
    Réponses: 2
    Dernier message: 18/06/2009, 09h44
  2. Composite control et listbox
    Par topolino dans le forum ASP.NET
    Réponses: 6
    Dernier message: 18/12/2008, 10h38
  3. Composite control debug
    Par topolino dans le forum ASP.NET
    Réponses: 0
    Dernier message: 17/12/2008, 10h08
  4. Controls.Canvas & évènement mouseDown
    Par Kikos31 dans le forum Windows Presentation Foundation
    Réponses: 2
    Dernier message: 14/07/2008, 09h43
  5. Problèmes user control et événement
    Par gridin dans le forum VB.NET
    Réponses: 3
    Dernier message: 04/05/2007, 14h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo