Un exemple est toujours mieux qu’un long discours, ci dessous une page asp.net faisant l’affichage dynamique de custom contrôle en fonction du type de données récupéré.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="EditDashBoard.aspx.cs" Inherits="Admin_Dashboard_EditDashBoard" %>
<%@ Register TagPrefix="uc1" TagName="uCtrlTitle" Src="../../Include/UserControls/uCtrlTitle.ascx" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<META HTTP-EQUIV="Pragma" CONTENT="no-cache" />
<META HTTP-EQUIV="Expires" CONTENT="-1" />
<title>EditDashboard</title>
<link href="../../Css/standard/standard.css" type="text/css" rel="stylesheet" />
</head>
<body>
<form id="form1" runat="server">
<div style="text-align:center;margin-top:10px" align="center">
<table align="center" width="95%" border="0">
<tr>
<td align="center"><uc1:uctrltitle id="UCtrlTitle1" runat="server"></uc1:uctrltitle></td>
</tr>
</table>
</div>
<div style="text-align:center;margin-top:10px" align="center">
<asp:Panel id="Panelcontent" runat="server">
</asp:Panel>
</div>
</form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using MonProjet.Business.DashBoard;
using MonProjet.DAL.Objects;
using MonProjet.DAL.DatasContexts.DashBoard;
using MonProjetV2.Include.Controls.Dashboard;
/// <summary>
/// Page d'édition de control panel
/// </summary>
public partial class Admin_Dashboard_EditDashBoard : BasePage
{
/// <summary>
/// Liste servant a recréer des controles dynamiques
/// </summary>
List<DynamicControlForViewState> DynamicControls
{
get
{
if (ViewState["DynamicControls"] == null)
{
ViewState["DynamicControls"] = new List<DynamicControlForViewState>();
}
return (List<DynamicControlForViewState>)ViewState["DynamicControls"];
}
set
{
ViewState["DynamicControls"] = value;
}
}
/// <summary>
/// Chargement de la page, récupération de l'id du dashboard à éditer
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Page_Load(object sender, EventArgs e)
{
Translation();
if (!Page.IsPostBack)
{
if (PreviousPage != null)
{
try
{
//Récupération de l'id du control panel
int l_DashBoardId = -1;
string l_Tmp = ((HiddenField)Page.PreviousPage.Controls[0].FindControl("Hd_DashBoardId")).Value;
if (!int.TryParse(l_Tmp, out l_DashBoardId))
{
//TODO error
Response.Write("ERROR");
}
else
{
if (l_DashBoardId > 0)
{
//TODO affichage
LoadControls(l_DashBoardId, GetLanguageId());
return;
}
else
{
//TODO error
Response.Write("ERROR");
}
}
}
catch
{
//TODO error
Response.Write("ERROR");
}
}
}
else {
ReLoadDynamicControls();
}
}
#region private
/// <summary>
/// Traduction
/// </summary>
private void Translation()
{
UCtrlTitle1.SetTitle(Translate("EDITDASHBOARD"));
}
/// <summary>
/// Rechargement des controls apres un postback par exemple
/// </summary>
private void ReLoadDynamicControls()
{
foreach (DynamicControlForViewState val in DynamicControls)
{
//Création des parties à afficher en fonction de leur type
//NB : Ne pas oublier de rattacher les Events si besoins.
switch (val.ControlType)
{
case 1: //Cokpit Main part
var CockpitPart = new DashBoardMainPart();
CockpitPart.ID = val.ControlId;
Panelcontent.Controls.Add(CockpitPart);
break;
case 2: //Detail Main part
var DetailPart = new DashBoardMainPart();
DetailPart.ID = val.ControlId;
Panelcontent.Controls.Add(DetailPart);
break;
case 3: //Titre
var TitrePart = new DashBoardtitle();
TitrePart.ID = val.ControlId;
Panelcontent.Controls.Add(TitrePart);
break;
case 4: //Section
var SectionPart = new DashBoardMainPart();
SectionPart.ID = val.ControlId;
Panelcontent.Controls.Add(SectionPart);
break;
default: //Default part
var DefaultPart = new DashBoardMainPart();
DefaultPart.ID = val.ControlId;
Panelcontent.Controls.Add(DefaultPart);
break;
}
}
}
/// <summary>
/// Charge les controles depuis une liste
/// </summary>
/// <param name="l_Res"></param>
private void LoadControlsFromList(List<DashBoardLine> l_Res)
{
List<DynamicControlForViewState> l_ControlList = new List<DynamicControlForViewState>();
foreach (DashBoardLine val in l_Res)
{
//Création des parties à afficher en fonction de leur type
switch (val.TypCtrlPanelLgn_Id)
{
case 1: //Cokpit Main part
var CockpitPart = new DashBoardMainPart();
CockpitPart.ID = string.Format("{0}{1}","CockpitPart",val.CtrPanelLgn_Id.ToString());
CockpitPart.Text = val.CtrPanelLgnTrans_Label;
CockpitPart.LigneId = val.CtrPanelLgn_Id;
CockpitPart.DashBoardId = val.CtrlPanel_Id;
Panelcontent.Controls.Add(CockpitPart);
l_ControlList.Add(new DynamicControlForViewState(1, CockpitPart.ID));
break;
case 2: //Detail Main part
var DetailPart = new DashBoardMainPart();
DetailPart.ID = string.Format("{0}{1}", "DetailPart", val.CtrPanelLgn_Id.ToString());
DetailPart.Text = val.CtrPanelLgnTrans_Label;
DetailPart.LigneId = val.CtrPanelLgn_Id;
DetailPart.DashBoardId = val.CtrlPanel_Id;
Panelcontent.Controls.Add(DetailPart);
l_ControlList.Add(new DynamicControlForViewState(2, DetailPart.ID));
break;
case 3: //Titre
var TitrePart = new DashBoardtitle();
TitrePart.ID = string.Format("{0}{1}", "TitrePart", val.CtrPanelLgn_Id.ToString());
TitrePart.Text = val.CtrPanelLgnTrans_Label;
Panelcontent.Controls.Add(TitrePart);
l_ControlList.Add(new DynamicControlForViewState(3, TitrePart.ID));
break;
case 4: //Section
var SectionPart = new DashBoardMainPart();
SectionPart.ID = string.Format("{0}{1}", "SectionPart", val.CtrPanelLgn_Id.ToString());
SectionPart.Text = val.CtrPanelLgnTrans_Label;
Panelcontent.Controls.Add(SectionPart);
l_ControlList.Add(new DynamicControlForViewState(4, SectionPart.ID));
break;
default: //Default part
var DefaultPart = new DashBoardMainPart();
DefaultPart.ID = string.Format("{0}{1}", "DefaultPart", val.CtrPanelLgn_Id.ToString());
DefaultPart.Text = val.CtrPanelLgnTrans_Label;
Panelcontent.Controls.Add(DefaultPart);
l_ControlList.Add(new DynamicControlForViewState(1, DefaultPart.ID));
break;
}
}
//Svg dans le viewstate la liste des controles de la page
//On ne sauvegarde que le type, le contenu des controles est conservé par le viewstate de ses controles enfants
DynamicControls = l_ControlList;
}
/// <summary>
/// Chargement des lignes
/// </summary>
/// <param name="DashBoardId">Id du dashboard</param>
/// <param name="LangueId">Langue devant être chargé</param>
private void LoadControls(int DashBoardId, int LangueId)
{
var L_LstLines = Dashboard.Get_DashBoardLines(DashBoardId, LangueId);
LoadControlsFromList(L_LstLines);
}
#endregion
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
/// <summary>
/// Objet permettant de Sauvegarder l'id et le type d'un control,
/// utilisé par exemple dans des listes de controles dynamique stockées en viewstate
/// </summary>
[Serializable]
public class DynamicControlForViewState
{
public int ControlType { get; set; }
public string ControlId { get; set; }
public DynamicControlForViewState()
{
}
public DynamicControlForViewState(int NType,String NId)
{
ControlId = NId;
ControlType = NType;
}
}
using System;
using System.ComponentModel;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace MonProjetV2.Include.Controls.Dashboard
{
/// <summary>
/// Control utlisé dans le dashboard pour affiché les titres de grandes parties
/// </summary>
public class DashBoardMainPart : WebControl, IPostBackEventHandler
{
/// <summary>
/// Constructeur, maintient également les controles
/// </summary>
public DashBoardMainPart()
: base()
{
//Maintient le contenu des controls
this.EnsureChildControls();
}
#region properties
/// <summary>
/// Nom utilisé à la génération des Id des controles enfants
/// </summary>
private string ControlDisplayTypeName = "DashBoardMainPartControl";
/// <summary>
/// Image button permettant d'ajouter un titre
/// </summary>
protected ImageButton AddTitleButton = new ImageButton();
/// <summary>
/// Text principal affiché dans l'encadré
/// </summary>
protected Literal MainText = new Literal();
/// <summary>
/// Conserve le contenue du MainText à travers les postback
/// </summary>
protected HiddenField HDMainTextValue = new HiddenField();
/// <summary>
/// Champs caché permettant de maintenir le numéro de ligne
/// </summary>
protected HiddenField HDLigneId = new HiddenField();
/// <summary>
/// Champs caché permettant de maintenir le numéro de dashboard
/// </summary>
protected HiddenField HDDashBoardId = new HiddenField();
/// <summary>
/// Control de test pour vérifier que le viewstate d'un contrôle est bien conservé après un postback
/// </summary>
protected TextBox TxtTest = new TextBox();
[
Description("Le texte affiché dans l'encadré principal"),
DefaultValue(""),
Localizable(true)
]
public string Text
{
get {
if (string.IsNullOrEmpty(MainText.Text))
if (!string.IsNullOrEmpty(HDMainTextValue.Value))
MainText.Text = HDMainTextValue.Value;
else
MainText.Text = string.Empty;
return this.MainText.Text;
}
set {
HDMainTextValue.Value = value;
this.MainText.Text = value;
}
}
[
Description("Identifiant de la ligne"),
DefaultValue(-1),
Localizable(true)
]
public int LigneId
{
get
{
string s = HDLigneId.Value;
if (!string.IsNullOrEmpty(s))
{
int OutResult;
if (int.TryParse(s, out OutResult))
return OutResult;
else
return 0;
}
else
return 0;
}
set
{
this.HDLigneId.Value = value.ToString();
}
}
[
Description("Identifiant du DashBoard"),
DefaultValue(-1),
Localizable(true)
]
public int DashBoardId
{
get
{
string s = HDDashBoardId.Value;
if (!string.IsNullOrEmpty(s))
{
int OutResult;
if (int.TryParse(s, out OutResult))
return OutResult;
else
return 0;
}
else
return 0;
}
set
{
this.HDDashBoardId.Value = value.ToString();
}
}
#endregion
#region Gestion des controles enfants
/// <summary>
/// Ajout des controles enfants à la collection du custom control,
/// permet de maintenir le control apres un postback(Viewstates etc.etc.)
/// </summary>
protected override void CreateChildControls()
{
//Init
AddTitleButton.ImageUrl = ResolveUrl("~/Images/icons/icon_add.gif");
//AddControls
this.Controls.Add(AddTitleButton);
this.Controls.Add(MainText);
this.Controls.Add(HDLigneId);
this.Controls.Add(HDDashBoardId);
this.Controls.Add(HDMainTextValue);
}
#endregion
#region EventsHandler
/// <summary>
/// EventHandler déclenché à l'ajout d'un titre
/// </summary>
public event EventHandler CreateTitle;
/// <summary>
/// Evenement déclenché par le click de l'ajout de titre
/// </summary>
/// <param name="Sender"></param>
/// <param name="e"></param>
protected virtual void AddTitleButton_Click(object Sender, EventArgs e)
{
//Si des méthodes sont abonnées alors on déclenche l'événement
if (CreateTitle != null)
{
CreateTitle(this, e);
}
//Traitement systematique
HttpContext.Current.Response.Write("POSTBACK ADD TITLE!!!! de "+this.ID.ToString()+" valeur post : "+TxtTest.Text );
}
// Remonté du posteBack, gestion manuel
public void RaisePostBackEvent(string eventArgument)
{
AddTitleButton_Click(this,new EventArgs());
}
/// <summary>
/// Ajout des références de postback sur les controles concernés
/// </summary>
/// <param name="writer"></param>
private void AddPostBackReference(HtmlTextWriter writer)
{
//L'ajout de return false permet d'empecher le postback de formulaire au profit de notre postback
writer.AddAttribute(HtmlTextWriterAttribute.Onclick,
Page.ClientScript.GetPostBackEventReference(this, "CreateTitle")+";return false;");
AddTitleButton.Attributes.AddAttributes(writer);
}
#endregion
/// <summary>
/// Gestion du rendu graphique du control
/// </summary>
/// <param name="writer"></param>
protected override void RenderContents(HtmlTextWriter writer)
{
//Render
if (Visible)
{
//Postback, gestion manuel des liaisons
AddPostBackReference(writer);
//Init des valeurs
MainText.Text = Text;
//Header
writer.Write(@"
<!-- Control DashBoardMainPart-->
<div style='text-align:center;margin-top:10px' align='center'>
<LINK href='" + ResolveUrl("~/Css/standard/standard.css") + @"' type='text/css' rel='stylesheet'>
");
//Bandeaux
writer.Write(@"
<TABLE id='tblzTitre' cellSpacing='0' cellPadding='0' width='95%' align='center' border='0'>
<TR>
<TD><table width='100%' class='cTblTitle'>
<tr>
<td align='center' valign='middle'>
<B>");
MainText.RenderControl(writer);
writer.Write(@"</B>
</td>
</tr>
</table>
</TD>
<TD class='cLngBorderRightS1' width='3'></TD>
</TR>
<TR>
<TD class='cLngBorderBottomS1' colSpan='2' height='3' width='100%'></TD>
</TR>
</TABLE>
");
//Rendu des controles enfants
writer.Write("<div style='text-align:right;margin-top:10px' align='right'>");
AddTitleButton.RenderControl(writer);
writer.Write("</div>");
TxtTest.RenderControl(writer);
HDMainTextValue.RenderControl(writer);
HDLigneId.RenderControl(writer);
HDDashBoardId.RenderControl(writer);
//Footer
writer.Write(@"
</div>
<!-- / Control DashBoardMainPart -->
");
}
}
}
}