[ASP.Net] Container-control

Pagina: 1
Acties:

  • maikel
  • Registratie: Januari 2001
  • Laatst online: 13:52
Ik ben nu in ASP.Net (C#) net aan de gang gegaan met User Control en dat werkt erg handig.
Maar nu vraag ik me af of het mogelijk is een control te schrijven waarin ik weer HTML-code kan zetten.
Dus iets als dit"
code:
1
2
3
4
<maikel:MyTable ID="myTable1" runat="server">
    <h1>Hier komt wat tekst</h1>
    <input type="text" id="naam">
</maikel:Mytable>


En dat mijn control (MyTable) dan bijv. daar het volgende van maakt:
code:
1
2
3
4
5
6
7
8
<table>
    <tr>
        <td>
            <h1>Hier komt wat tekst</h1>
            <input type="text" id="naam">
        </td>
    </tr>
</table>


Ik heb uiteraard al wel met Google gezocht, maar daar kwam ik alleen het dynamisch toevoegen van controls tegen en niet het toevoegen van control in de HTML-code.

Verwijderd

Je kan toch een property toevoegen (bv. HtmlText) en alle text die daarin staat wordt bij het renderen (daar is een event voor) gewoon tussen de <td> tags gegooid.
Of wil je de HTML die op je control komt grafisch kunnen designen?

  • maikel
  • Registratie: Januari 2001
  • Laatst online: 13:52
Met een zo'n dingetje kan dat wel ja, maar niet als je bijv. een hele grote tabel er tussen wilt zetten. Nogal onhandig om dat dan aan die property toe te kennen. :)

  • maikel
  • Registratie: Januari 2001
  • Laatst online: 13:52
Iemand nog een goed idee ?

  • maikel
  • Registratie: Januari 2001
  • Laatst online: 13:52
Ik heb het nu zelf opgelost. Ik moest gebruik maken van een template.

Code-behind van de usercontrol
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
namespace amelsfort
{
    using System;
    using System.Data;
    using System.Drawing;
    using System.Web;
    using System.Web.UI.WebControls;
    using System.Web.UI.HtmlControls;
    using System.Web.UI;

    /// <summary>
    ///     Summary description for Control.
    /// </summary>
    [ParseChildren(true)]
    public abstract class TestControl : UserControl, INamingContainer
    {
        private ITemplate main;
        protected PlaceHolder container;

        public ITemplate Main
        {
            get
            {
                return main;
            }
            set
            {
                main = value;
            }
        }

        protected override void CreateChildControls()
        {
            if (Main != null)
            {
                main.InstantiateIn(container);
            }
        }
    }
}


De aspx-file van de usercontrol
code:
1
2
3
4
5
6
7
8
9
<%@ Control Language="c#" AutoEventWireup="false"
Codebehind="Control.ascx.cs" Inherits="amelsfort.TestControl"
TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%>
<table>
    <tr>
        <td>Test:</td>
        <td><asp:PlaceHolder ID="container" Runat="server" /></td>
    </tr>
</table>


M'n webform
code:
1
2
3
4
5
6
<Amelsfort:TestControl id="control" runat="Server">
    <main>
        test
        <asp:TextBox Runat="server" ID="blabla">blablabla</asp:TextBox>
    </main>
</Amelsfort:TestControl>


Dit werkt op zich wel lekker. Maar levert wel weer een ander probleem op. Ik kan nu in m'n webform niet meer zomaar bij de objecten dit binnen de template vallen (de textbox dus).
Nu zag ik op Google wel iemand met hetzelfde probleem en de oplossing.
Maar ik volg het nog niet helemaal.
Ik heb nu de ITemplate vervangen door een PlaceHolder, maar nu wordt er niets meer gerenderd.
Weet iemand hoe ik dit kan oplossen ?

  • alley
  • Registratie: Mei 2002
  • Laatst online: 18-08 20:40

alley

ahuh

Je kunt je control overerven van een PlaceHolder en de render method overriden, zodat je je eigen HTML om de PlaceHolder heen kunt gooien

I am always doing that which I can not do, in order that I may learn how to do it. (Pablo Picasso)


  • maikel
  • Registratie: Januari 2001
  • Laatst online: 13:52
Wat zou ik dan in de bovenstaande code moeten aanpassen ?
Kan ik dan ook nog werken met HTML die ik tussen de usercontrol-tags zet ?

  • alley
  • Registratie: Mei 2002
  • Laatst online: 18-08 20:40

alley

ahuh

Je kunt vanuit je webform dan gewoon je controls binnen de usercontrol benaderen ja...
Zoiets wordt het dan:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class TestControl : PlaceHolder
{
        override protected void Render(HtmlTextWriter writer)
        {
            writer.WriteFullBeginTag("table");
            writer.WriteFullBeginTag("tr");
            writer.WriteFullBeginTag("td");
                writer.Write("Test:");
            writer.WriteEndTag("td");
            writer.WriteFullBeginTag("td");
                //render the contents
                base.Render(writer);

            writer.WriteEndTag("td");
            writer.WriteEndTag("tr");
            writer.WriteEndTag("table");
        }
    }


Je aanroep:
code:
1
2
3
4
<Amelsfort:TestControl id="control" runat="Server">
    test
    <asp:TextBox Runat="server" ID="blabla">blablabla</asp:TextBox>
</Amelsfort:TestControl>


(Dus zonder <main> tags)

[ Voor 0% gewijzigd door alley op 06-11-2002 15:55 . Reden: aanroep vergeten :D ]

I am always doing that which I can not do, in order that I may learn how to do it. (Pablo Picasso)


  • maikel
  • Registratie: Januari 2001
  • Laatst online: 13:52
Aha !
Dat scheelt al een stuk. Maar het makkelijkst zou het dan nog zijn als je niet alle objecten dmv writer.Write() hoeft aan te maken maar het gewoon als HTML ergens toe kunt voegen.

  • alley
  • Registratie: Mei 2002
  • Laatst online: 18-08 20:40

alley

ahuh

Je zou het in een file kunnen plaatsen, die uitlezen en met writer.Write() die string outputen...

Maar bovenstaande manier is wel veel netter, ook al is het meer werk.

I am always doing that which I can not do, in order that I may learn how to do it. (Pablo Picasso)


  • maikel
  • Registratie: Januari 2001
  • Laatst online: 13:52
Ik schop even dit (oude) topic weer omhoog omdat ik nu de oplossing heb gevonden !
En aangezien het erg handig werkt, wil ik dat jullie toch niet onthouden. :)

De ascx-file voor de PageContainer:
HTML:
1
2
3
4
5
6
7
8
<%@ Control Language="c#" AutoEventWireup="false" Codebehind="PageContainer.ascx.cs" Inherits="Maikel.PageContainer" TargetSchema="http://schemas.microsoft.com/intellisense/ie5" %>
<table border="0" cellpadding="0" cellspacing="0" width="100%" height="100%">
    <tr height="100%">
        <td>
            <asp:PlaceHolder id="bodyContainer" runat="server" />
        </td>
    </tr>
</table>


De codebehind voor de PageContainer:
C#:
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
namespace Maikel
{
    using System;
    using System.Data;
    using System.Drawing;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.HtmlControls;
    using System.Collections;
    using System.Collections.Specialized;
    using System.Text;

    /// <summary>
    ///     Summary description for PageContainer.
    /// </summary>
    [ParseChildren(ChildrenAsProperties = true)] 
    public abstract class PageContainer : UserControl
    {
        protected PlaceHolder bodyContainer;
        private PlaceHolder body;

        protected PageContainer()
        {
            this.Load       += new System.EventHandler(this.Page_Load);
            this.Init       += new System.EventHandler(OnInit);
        }       

        private void Page_Load(object sender, System.EventArgs args)
        {
        }

        public PlaceHolder Body
        {
            get
            {
                return body;
            }
            set
            {
                body = value;
            }
        }
        protected void OnInit(object sender, EventArgs args)
        {
            if (body != null)
            {
                bodyContainer.Controls.Add(body);
            }
        }
    }
}


Het gebruik in een aspx-pagina:
HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<%@ Page language="c#" Codebehind="PageContainerTest.aspx.cs" AutoEventWireup="false" Inherits="Maikel.PageContainerTest" %>
<%@ Register TagPrefix="vtw" TagName="PageContainer" src="PageContainer.ascx" %>
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<html>
    <head>
        <title>PageContainer test</title>
    </head>
    <body>
        <form method="post" runat="server" ID="Form1">
            <vtw:pagecontainer id="pageContainer" runat="server">
                <body>
                    Blablablabla
                    <asp:TextBox id="text1" runat="server" />
                </body>
            </vtw:pagecontainer>
        </form>
    </body>
</html>


In de codebehind van de aspx-pagina kun je nu gewoon alle objecten die tussen de body-tags van in de PageContainer staan als 'protected' declareren en gebruiken zoals in elke andere aspx-pagina.
Voordeel is nu wel dat je in de ascx-file (de control zelf dus) een hele hoop design-onderdelen die nooit wijzigen kunt plaatsen. Alles wat tussen de body-tags van de PageContainer staat wordt op de plaats van de bodyContainer-placeholder gezet. Ook kun je in de ascx-file gewoon weer alle controls gebruiken die je normaal ook kunt gebruiken. Deze zijn dan alleen toegankelijk vanuit de codebehind van de control.

Ik hoop dat het een beetje duidelijk is allemaal.
Zo niet, mail me maar. :)

Ik gebruik 'm nu door het hele project waar ik nu mee bezig ben. Erg handig aangezien ik me nu helemaal geen zorgen meer hoef te maken om het design en in de aspx-file komt nu alleen HTML die specifiek voor die pagina is.

[ Voor 10% gewijzigd door maikel op 06-12-2002 12:49 ]


Verwijderd

Ziet er wel leuk uit :). Dus je kan gewoon de form designer gebruiken of controls op de PageContainer te gooien :?. Dat zou idd wel heel handig zijn :).

  • maikel
  • Registratie: Januari 2001
  • Laatst online: 13:52
De designer kun je niet gebruiken helaas (denk ik). Maar ja, die gebruik ik ook nooit. :)
Wat je wel kunt doen is in de designer de pagina (het unieke gedeelte dus) bouwen en dan daarna in code-view de PageContainer er omheen zetten zodat die het design er omheen plaatst.
Pagina: 1