2013-05-01 2 views
3

Je suis en train de mettre en place un site Web qui récupère le contenu d'une base de données et le remplit dans un composant qui est ensuite chargé sur la page. Le hic, c'est qu'il y a beaucoup de composants différents qui sont inconnus au moment de la compilation et que je veux appeler à partir de la base de données.Ajout dynamique de contrôles de type inconnu et de méthodes d'appel sur le contrôle

Par exemple, il peut y avoir plusieurs composants tels que:

  • modContent.ascx
  • modSlidingBanner.ascx
  • modEmailSlug.ascx

et la base de données contiendra une table champs définissant le module à utiliser et le contenu à charger:

  • ModuleName: "modContent"
  • Contenu: "zippidy doo da"

Alors disons que modContent.ascx ressemble:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="modContent.ascx.cs" Inherits="modContent" %> 

<div class="content"> 
    <div class="content-wrapper" ID="divContentWrapper" runat="server"> 
     <asp:Literal ID="litContent" runat="server"></asp:Literal> 
    </div> 
</div> 

Et modContent.ascx.cs contient la méthode:

public void FillIn(string html) 
{ 
    litContent.Text = html; 
} 

Et sur ma page principale, je veux charger ce contrôle et appeler la méthode FillIn. Je peux le faire facilement si je connais le type de commande à l'avance:

modContent c = LoadControl("~/modContent.aspx"); 
c.FillIn(ContentFromDatabase); 
divTargetPanel.Controls.Add(c); 

Cependant, comme je l'ai mentionné, je veux choisir l'un de plusieurs contrôles basés sur une chaîne dans la base de données. Je peux garantir que chacun de ces contrôles aura la méthode FillIn. Et je voudrais éviter d'avoir une grande clause de changement ou quelque chose où je dois changer le code sur la page principale chaque fois que j'ajoute un nouveau contrôle qui pourrait être utilisé.

je peux obtenir un module chargé sur la page comme ceci:

Control c = LoadControl("~/" + ControlNameFromDatabase + ".aspx"); 
divTargetPanel.Controls.Add(c); 

mais ne peut pas appeler la méthode fillin sur ce contrôle.

je peux déplacer la fonctionnalité de la méthode fillin au constructeur pour le contrôle et essayez ceci:

Assembly assembly = typeof(ControlsParentClass).Assembly; 
Type type = assembly.GetType(ControlNameFromDatabase); 
skinHome.divContentPanel.Controls.Add(LoadControl(type, new object[] { ContentFromDatabase })); 

Mais, cette erreur parce que litContent retours null dans modContent.ascx.cs comme décrit dans this guy's question.

De toute évidence, le contrôle décrit ci-dessus est très simple. Je l'ai dépouillé jusqu'aux bases. Les modules seront en réalité beaucoup plus complexes, chacun avec leur propre structure et code, mais avec des noms/arguments de méthode identiques.

Est-ce que je vais dans ce sens?

Répondre

2

Déclarez une interface contenant tous vos publics méthodes et propriétés

public interface IMyControl 
{ 
    void FillIn(string html); 
} 

héritera de toutes vos commandes de cette interface:

public partial class modContent : Control, IMyControl 

jeté toutes vos commandes à IMyControl et appelez FillIn

IMyControl c = LoadControl("~/modContent.aspx") as IMyControl; 
c.FillIn(ContentFromDatabase); 
divTargetPanel.Controls.Add(c as Control); 
+0

A travaillé magnifiquement avec la petite exception d'avoir besoin d'utiliser 'divTargetPanel.Controls.Add (c comme contrôle);' Merci beaucoup! – e2579382

+0

mis à jour pour refléter le commentaire ci-dessus. – Liam

Questions connexes