2009-04-03 2 views
5

Existe-t-il un moyen accepté de "déplacer" un contrôle.Comment pouvez-vous déplacer des contrôles ASP.Net à différents endroits sur le formulaire Web lors de l'exécution?

Mon client souhaite placer un certain bloc de balisage (représentant un élément visuel) dans l'un des différents endroits de la page. Les emplacements sont différents au point que je ne peux pas effectuer le changement sur CSS (en le faisant flotter ou quelque chose).

Je considérais simplement de mettre le contrôle dans plusieurs endroits avec Visible réglé sur "false", puis d'afficher celui à l'endroit qu'ils voulaient pour cette page particulière.

Cependant, le code pour ce contrôle n'est pas trivial - il y a quelques sections de modèle, par exemple. Devoir duper cela à plusieurs endroits serait difficile. Aussi, je ne veux pas avoir à travailler avec ce contrôle strictement du code-behind pour la même raison. Donc, je voudrais le mettre en un seul endroit sur le formulaire Web, le déplacer autour de l'endroit où je le veux. Pourrais-je placer des espaces réservés dans différents endroits, avoir le contrôle en un endroit, puis le retirer et l'ajouter au bon endroit? Je soupçonne que cela fonctionnerait.

Quelqu'un a-t-il une meilleure idée? Y a-t-il une meilleure pratique pour cela?

Répondre

5

Je vous recommande d'utiliser un contrôle d'espace réservé, déplacer votre balisage dans un contrôle utilisateur séparé, le chargement alors ce lors de l'exécution et l'ajouter à l'espace réservé pertinent.

Par exemple.

// Load a user control 
MyControl userCtrl = (MyControl) LoadControl("~/Controls/MyControl.ascx"); 

// Or create an instance of your control 
SubclassedControl subclassedCtrl = new SubclassedControl(); 

// Do stuff with controls here 
userCtrl.LoadData(); 
subclassedCtrl.Text = "Hello World"; 

// Check which placeholder to add controls to 
PlaceHolder placeHolder = (foo=="bar") ? placeHolder1 : placeHolder2; 

// Add the controls 
placeHolder.Controls.Add(userCtrl); 
placeHolder.Controls.Add(subclassedCtrl); 

Cela évitera d'encombrer votre page avec un balisage inutile, et le charger à l'exécution permettra également d'éviter une confusion inutile plus tard, un autre développeur regarde le code et ne peut pas voir immédiatement pourquoi un contrôle est en un seul endroit dans le balisage, mais rend sur une partie complètement différente de la page.

+0

Comment est-ce que je ferais ceci si le contrôle est une extension d'un contrôle ASP.Net standard, ainsi il existe comme un fichier .cs dans App_Code? Aurais-je besoin de "l'envelopper" dans un contrôle utilisateur (un fichier .ascx)? – Deane

+0

Oui, alors vous pouvez soit le charger dans un espace réservé ou un panneau .. même diff, seul le panneau crache une balise div ou span où l'espace réservé ne le fait pas. – madcolor

+0

Si vous sous-classez un contrôle ASP.NET standard, vous pouvez créer une instance de votre contrôle au lieu de charger un contrôle, puis l'ajouter à l'espace réservé. J'ai mis à jour l'exemple de code ci-dessus pour refléter cela. – Mun

2

Est-ce que les composants WebPart font ce que vous voulez faire? Ou, vous pouvez modifier le parent de vos contrôles par programme pour les déplacer dans une zone distincte.

0

Vous pouvez toujours placer des panneaux dans les emplacements prédéfinis et ajouter le contrôle au panneau spécifique lors de l'exécution. Voici un exemple d'ajout d'une étiquette (l'étiquette pourrait être remplacée par n'importe quel contrôle).

Dim lblDisplay As Label = New Label() 
lblDisplay.ID = "myLabel" 
lblDisplay.Text = "Some Text" 
pnlDisplay.Controls.Add(lblDisplay) 

En ce qui concerne ...

« Aussi, je ne veux pas avoir à travailler avec ce contrôle strictement du code-behind pour la même raison. »

Je pense que vous allez devoir faire la plupart de votre travail dans le code derrière.

PS .. un bon exemple de l'ensemble de l'installation UserControl peut être téléchargé ici .. http://www.asp.net/downloads/starter-kits/time-tracker/

+0

Je voulais dire que je ne voulais pas le créer à partir du code-behind. Je n'ai aucun problème à le manipuler sous une forme ou une autre à partir du code-behind, mais j'aimerais que la majeure partie de cette marque soit ajoutée au formulaire Web. – Deane

+0

Je vous suggère de créer un contrôle utilisateur avec le balisage qui a des propriétés que vous pouvez obtenir/définir et charger un panneau. Aucune bonne raison d'avoir votre balisage assis dans le webform que je peux voir. – madcolor

1

Vous pouvez remplacer la méthode de rendu et placez les contrôles là où vous voulez dans le code HTML.

Vous devez uniquement ajouter des contrôles à la collection Controls qui doit interagir sur le serveur. Le reste de votre HTML peut simplement être écrit dans le flux de réponse. Si vous substituez Render, vous pouvez créer le code HTML de votre choix, en plaçant les contrôles dans n'importe quel ordre.

Voici un exemple de comment écrire votre code HTML.

protected override void Render(HtmlTextWriter writer) 
{ 
    AddAttributesToRender(writer); 
    writer.RenderBeginTag(TagKey); 

    writer.RenderBeginTag(HtmlTextWriterTag.Div); 
    _control.RenderControl(writer); 
    writer.RenderEndTag(); 

    writer.RenderEndTag(); 
} 
3

Une alternative (et une que j'ai déjà vu plusieurs fois) est via javascript et le DOM. Rendez votre contrôle à l'intérieur d'un tag div caché. Donc, vous rendre votre contenu ici:

<div id='rendercontent' style='display:none'> 
    .. control here .. 
</div> 

Ensuite, permet de dire que vous vouliez déplacer tout ici (la balise span est à l'intérieur parce que ce que nous allons remplacer):

<div id='newlocation1'><span></span></div> 

vous définiriez le javascript suivant:

<script language="JavaScript"> 
function replaceNode(newElementID, targetElementID) 
{ 
    var targetElement=document.getElementById(targetElementID); 
    var newElement=document.getElementById(newElementID); 
    targetElement.replaceChild(newElement, targetElement.firstChild); 
} 
</script> 

Et quand vous voulez déplacer le contenu vers le nouvel emplacement, appelez:

<script language="JavaScript"> 
replaceNode('rendercontent','newlocation1'); 
</script> 
Questions connexes