Composite Control et évènements
J'ai construit un Custom Composite Control qui contient 2 Interface ITemplate:
- HeaderTemplate
- 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:
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
1 pièce(s) jointe(s)
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:
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:
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:
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.