[C#][AS.NET] problème rendu custom web control

Résolu
outcast_fr Messages postés 11 Date d'inscription jeudi 10 novembre 2005 Statut Membre Dernière intervention 11 avril 2006 - 7 mars 2006 à 18:17
outcast_fr Messages postés 11 Date d'inscription jeudi 10 novembre 2005 Statut Membre Dernière intervention 11 avril 2006 - 8 mars 2006 à 17:30
Bonjour,

j'ai créé un custom web control comportant un zone de saisie éditable.
On peut y ajouter du texte ou d'autres web controls via le designer par un simple glissé déposé.

Tout marche très bien dans le designer, je peux par exemple ajouter 2 boutons.

Le problème c'est que lorsque je lance ma page asp.net, j'ai bien le cadre (la couleur de fond) de mon custom web control mais aucun bouton n'est ajouté.

Savais-vous d'où peut venir le problème ?
Merci

Voici le code :


Code:,
----

using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Web.UI;
using System.Web.UI.Design;
using System.Web.UI.Design.WebControls;
using System.Web.UI.WebControls;

namespace Samples.ASPNet.ControlDesigners_CS
{
[Designer(typeof(MyMultiRegionControlDesigner)),
ToolboxData("<{0}:MyMultiRegionControl runat=\"server\" width=\"200\"></{0}:MyMultiRegionControl>")]
public class MyMultiRegionControl : CompositeControl
{
// Define the templates that represent 2 views on the control
private ITemplate _view;

// Create persistable inner properties
// for the two editable views
[PersistenceMode(PersistenceMode.InnerProperty), DefaultValue(null)]
public virtual ITemplate View
{
get { return _view; }
set { _view = value; }
}

// Create a simple table with a row of two clickable,
// readonly headers and a row with a single column, which
// is the 'container' to which we'll be adding controls.
protected override void CreateChildControls()
{
// Always start with a clean form
Controls.Clear();

// Create a table using the control's declarative properties
Table t = new Table();
t.CellSpacing = 1;
t.BorderStyle = BorderStyle;
t.Width = this.Width;
t.Height = this.Height;

// Create the header row
TableRow tr = new TableRow();
tr.HorizontalAlign = HorizontalAlign.Center;
tr.BackColor = Color.LightBlue;
tr.HorizontalAlign = HorizontalAlign.Center;

// This cell represents our content 'container'
TableCell tc = new TableCell();
tc.Height = new Unit(20);
tr.Cells.Add(tc);

t.Rows.Add(tr);

// Add the finished table to the Controls collection
Controls.Add(t);
}

}

//---------------------------------------------------------
// Region-based control designer for the above web control,
// derived from CompositeControlDesigner.
public class MyMultiRegionControlDesigner : CompositeControlDesigner
{
private MyMultiRegionControl myControl;

public override void Initialize(IComponent component)
{
base.Initialize(component);
myControl = (MyMultiRegionControl)component;
}

// Make this control resizeable on the design surface
public override bool AllowResize
{
get
{
return true;
}
}

// Use the base to create child controls, then add region markers
protected override void CreateChildControls()
{
base.CreateChildControls();

// Get a reference to the table, which is the first child control
Table t = (Table)myControl.Controls[0];

// Add design time markers for each of the three regions
if (t != null)
{
t.Rows[0].Cells[0].Attributes[DesignerRegion.DesignerRegionAttributeName] = "0";
}
}

// Create the regions and design-time markup. Called by the designer host.
public override String GetDesignTimeHtml(DesignerRegionCollection regions)
{
// Create an editable region and add it to the regions
EditableDesignerRegion editableRegion =
new EditableDesignerRegion(this,
"Content", false);
regions.Add(editableRegion);

// Use the base class to render the markup
return base.GetDesignTimeHtml();
}

// Get the content string for the selected region. Called by the designer host?
public override string GetEditableDesignerRegionContent(EditableDesignerRegion region)
{
// Get a reference to the designer host
IDesignerHost host = (IDesignerHost)Component.Site.GetService(typeof(IDesignerHost));
if (host != null)
{
ITemplate template = myControl.View;

// Persist the template in the design host
if (template != null)
return ControlPersister.PersistTemplate(template, host);
}

return String.Empty;
}

// Create a template from the content string and
// put it in the selected view.
public override void SetEditableDesignerRegionContent(EditableDesignerRegion region, string content)
{
if (content == null)
return;

// Get a reference to the designer host
IDesignerHost host = (IDesignerHost)Component.Site.GetService(typeof(IDesignerHost));
if (host != null)
{
// Create a template from the content string
ITemplate template = ControlParser.ParseTemplate(host, content);

if (template != null)
{
myControl.View = template;
}
}
}
}
}

3 réponses

outcast_fr Messages postés 11 Date d'inscription jeudi 10 novembre 2005 Statut Membre Dernière intervention 11 avril 2006
8 mars 2006 à 17:30
Bon ben à force de chercher et rechercher, j'ai trouvé la solution à mon problème en me basant sur ces deux articles de la msdn.

Je ne sais pas si c'est la meilleur solution, mais elle a le mérite de fonctionner.

Ne me demandez pas par contre des détails sur le fonctionnement exact de "ma" solution, car moi-même je me demande parfois comment j'ai pu le faire
(en rouge les mises à jours par rapport au code précédent)


Code:,
----

using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Web.UI;
using System.Web.UI.Design;
using System.Web.UI.Design.WebControls;
using System.Web.UI.WebControls;

namespace Samples.ASPNet.ControlDesigners_CS
{
[Designer(typeof(MyMultiRegionControlDesigner)),
ToolboxData("<{0}:MyMultiRegionControl runat=\"server\" width=\"200\"></{0}:MyMultiRegionControl>")]
public class MyMultiRegionControl : CompositeControl
{
private Control myTemplateContainer;

// Define the templates that represent 2 views on the control
private ITemplate _view;

// Create persistable inner properties
// for the two editable views
[DefaultValue(null),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(ViewContainer))]
public virtual ITemplate MyView
{
get { return _view; }
set { _view = value; }
}

// Create a simple table with a row of two clickable,
// readonly headers and a row with a single column, which
// is the 'container' to which we'll be adding controls.
protected override void CreateChildControls()
{
// Always start with a clean form
Controls.Clear();

// Create a table using the control's declarative properties
Table t = new Table();
t.CellSpacing = 1;
t.BorderStyle = BorderStyle;
t.Width = this.Width;
t.Height = this.Height;

// Create the header row
TableRow tr = new TableRow();
tr.HorizontalAlign = HorizontalAlign.Center;
tr.BackColor = Color.LightBlue;

// This cell represents our content 'container'
TableCell tc = new TableCell();
tc.Height = new Unit(20);

//----------------------------------------------------
//----------------------------------------------------
if (MyView != null)
{
myTemplateContainer = new ViewContainer(this);
MyView.InstantiateIn(myTemplateContainer);
tc.Controls.Add(myTemplateContainer);
}
//----------------------------------------------------
//----------------------------------------------------

tr.Cells.Add(tc);
t.Rows.Add(tr);

// Add the finished table to the Controls collection
Controls.Add(t);

}

protected override void OnDataBinding(EventArgs e)
{
EnsureChildControls();
base.OnDataBinding(e);
}
}

public class ViewContainer : Control, INamingContainer
{
private MyMultiRegionControl parent;
public ViewContainer(MyMultiRegionControl parent)
{
this.parent = parent;
}
}

//---------------------------------------------------------
// Region-based control designer for the above web control,
// derived from CompositeControlDesigner.
public class MyMultiRegionControlDesigner : CompositeControlDesigner
{
private MyMultiRegionControl myControl;

public override void Initialize(IComponent component)
{
base.Initialize(component);
myControl = (MyMultiRegionControl)component;
}

// Make this control resizeable on the design surface
public override bool AllowResize
{
get
{
return true;
}
}

// Use the base to create child controls, then add region markers
protected override void CreateChildControls()
{
base.CreateChildControls();

// Get a reference to the table, which is the first child control
Table t = (Table)myControl.Controls[0];

// Add design time markers for each of the three regions
if (t != null)
{
t.Rows[0].Cells[0].Attributes[DesignerRegion.DesignerRegionAttributeName] = "0";
}
}

// Create the regions and design-time markup. Called by the designer host.
public override String GetDesignTimeHtml(DesignerRegionCollection regions)
{
// Create an editable region and add it to the regions
EditableDesignerRegion editableRegion =
new EditableDesignerRegion(this,
"Content", false);
regions.Add(editableRegion);

// Use the base class to render the markup
return base.GetDesignTimeHtml();
}

// Get the content string for the selected region. Called by the designer host?
public override string GetEditableDesignerRegionContent(EditableDesignerRegion region)
{
// Get a reference to the designer host
IDesignerHost host = (IDesignerHost)Component.Site.GetService(typeof(IDesignerHost));
if (host != null)
{
ITemplate template = myControl.MyView;

// Persist the template in the design host
if (template != null)
return ControlPersister.PersistTemplate(template, host);
}

return String.Empty;
}

// Create a template from the content string and
// put it in the selected view.
public override void SetEditableDesignerRegionContent(EditableDesignerRegion region, string content)
{
if (content == null)
return;

// Get a reference to the designer host
IDesignerHost host = (IDesignerHost)Component.Site.GetService(typeof(IDesignerHost));
if (host != null)
{
// Create a template from the content string
ITemplate template = ControlParser.ParseTemplate(host, content);

if (template != null)
{
myControl.MyView = template;
}
}
}
}
}

Vous pouvez effectuer un copier/coller du code et le générer directement.

Si vous avez des suggestions ou des améliorations à proposer, n'hésitez pas !
3
jesusonline Messages postés 6814 Date d'inscription dimanche 15 décembre 2002 Statut Membre Dernière intervention 13 octobre 2010 29
7 mars 2006 à 19:01
Bonjour

si on regarde seulement ton controle :

public class MyMultiRegionControl : CompositeControl
{
// Define the templates that represent 2 views on the control
private ITemplate _view;

// Create persistable inner properties
// for the two editable views
[PersistenceMode(PersistenceMode.InnerProperty), DefaultValue(null)]
public virtual ITemplate View
{
get { return _view; }
set { _view = value; }
}

// Create a simple table with a row of two clickable,
// readonly headers and a row with a single column, which
// is the 'container' to which we'll be adding controls.
protected override void CreateChildControls()
{
// Always start with a clean form
Controls.Clear();

// Create a table using the control's declarative properties
Table t = new Table();
t.CellSpacing = 1;
t.BorderStyle = BorderStyle;
t.Width = this.Width;
t.Height = this.Height;

// Create the header row
TableRow tr = new TableRow();
tr.HorizontalAlign = HorizontalAlign.Center;
tr.BackColor = Color.LightBlue;
tr.HorizontalAlign = HorizontalAlign.Center;

// This cell represents our content 'container'
TableCell tc = new TableCell();
tc.Height = new Unit(20);
tr.Cells.Add(tc);

t.Rows.Add(tr);

// Add the finished table to the Controls collection
Controls.Add(t);
}

}

on ne voit nul part que tu rajoutes tes boutons.

Avant de faire le mode design je finit déjà le mode normal ;) le mode design vient ensuite ... c'est souvent beaucoup plus facile car en plus dans 80% des cas le mode design ne sert jamais... (en tout cas pas pour moi)


<HR>
Cyril - MVS - MCP ASP
0
outcast_fr Messages postés 11 Date d'inscription jeudi 10 novembre 2005 Statut Membre Dernière intervention 11 avril 2006
8 mars 2006 à 10:01
C'est normal que l'on ne voit pas que j'ajoute les boutons, puisqu'ils sont ajoutés en mode design, dynamiquement (par un glisser/déposer).
Je parlais de boutons pour l'exemple, mais on peut y ajouter n'importe quels web controls (ou custom webcontrols).
Par contre sur la page HTML rendu, il n'y a aucun bouton (ou autre) ajouté.

Le problème c'est que si je place une méthode Render, je n'ai plus rien qui s'affiche dans le mode design (ou alors je ne sais pas m'en servir) hormis ce que j'ai écrit dans la méthode Render.

Ce que j'aimerais mais que je ne sais pas trop comment faire c'est générer les "ChildControls" (= ceux que l'ont ajoute dynamiquement par le designer).
0
Rejoignez-nous