Avatar billede davidfossil Nybegynder
19. september 2004 - 17:36 Der er 18 kommentarer og
1 løsning

Custom server control med array af "sub objects"

Jeg er interesseret i at lave en control der ligesom fx ListBox har en række objekter (her ListItems) tilknyttet i en slags "array parameter".

Nogen der har styr på hvordan man laver den slags controls? Jeg har en idé om at man måske skal bruge nogle ILists eller ICollections...?
Avatar billede snepnet Nybegynder
19. september 2004 - 17:42 #1
huhada... der kan være mange svar på den :o)

som udgangspunkt virker de fleste kontroller i sig selv som enumererbare containers.

Du kan f.eks. proppe en stak tekstbokse ind i et Panel, og "trævle dem op" bagefter :

foreach(Control c in this.Panel1.Controls)
{
  TextBox tb = (TextBox)c;
}

Du kan derfor uden problemer opnå den slags uden at foretage dig noget særligt.

Er ønsket at du vil lave en kontrol med mere typestærke "Items" har du selvfølgelig også mulighed for det.

Jeg vil meget gerne lave et lille eksempel til dig, hvis du er interesseret, men det kunne være fedt hvis du lige skrev noget lidt mere konkret om hvad du er ude efter.

mvh
Avatar billede snepnet Nybegynder
19. september 2004 - 17:44 #2
(mange af de medfølgende kontroller (datagrid, datalist, repeater, checkboxlist mv) kan det jo i forvejen.... så et lille hint omkring "det specielle" du er ude efter ville gøre det nemmere at lave et eksempel.
mvh
Avatar billede snepnet Nybegynder
19. september 2004 - 17:48 #3
(et datagrid holder f.eks. en datagriditemcollection, som ganske rigtig implementerer ICollection)
Avatar billede davidfossil Nybegynder
19. september 2004 - 17:54 #4
Det er i bund og grund en kontrol der kan holde en række HyperLinks jeg skal bruge.
Jeg kender godt .Controls, og bruger den også i dag til blot at tilføje min links til fx en PlaceHolder, men jeg ville gerne smække en mere struktureret kontrol sammen der kun tillader HyperLinks og som jeg selv definerer Render metoden for.
Avatar billede snepnet Nybegynder
19. september 2004 - 18:08 #5
Det er meget enkelt at lave en customcontrol, hvor du selv definerer renderingen. Hvis du ikke har prøvet det før kan vi lige starte med denne meget lille, og meget ligegyldige demo :

det er vældig enkelt at lave en customcontrol... en meget simpel kunne være sådan en som denne :

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace EXP2
{
    public class DavidFossil : System.Web.UI.Page
    {
        protected HtmlForm Form1;

        private void Page_Load(object sender, System.EventArgs e)
        {
            Form1.Controls.Add(new DemoControl());
        }

        override protected void OnInit(EventArgs e)
        {
            InitializeComponent();
            base.OnInit(e);
        }
       
        private void InitializeComponent()
        {   
            this.Load += new System.EventHandler(this.Page_Load);
        }
    }

    public class DemoControl : Control
    {
        protected override void Render(HtmlTextWriter writer)
        {
            writer.Write("hej der");
        }
    }
}
Avatar billede snepnet Nybegynder
19. september 2004 - 18:09 #6
(du får bare hele sourcen... så kan du paste det direkte ind og køre det).

Det er selvfølgelig denne her der er den interessante :

    public class DemoControl : Control
    {
        protected override void Render(HtmlTextWriter writer)
        {
            writer.Write("hej der");
        }
    }

En supersimpel sag, som ikke kan brugest til noget som helst... Men det er en custom serverkontrol, hvor renderingen styres af dig.
Avatar billede davidfossil Nybegynder
19. september 2004 - 18:13 #7
Jeg har fint styr på hvordan jeg bygger en custom server control og får dentil at rendere det jeg ønsker, hvorfor jeg forsøgte ikke at nævne det i mit oprindelige spørgsmål.

Det jeg ikke har styr på er hvordan jeg kan lave en parameter på min control som fungerer som et array af fx HyperLinks. Jeg vil gerne kunne tilføje, slette og overvåge de tilknyttede HyperLinks, på samme måde som man kan bruge minListBox.Items.Add(), minListBox.Items.Count ved en ListBox.
Avatar billede snepnet Nybegynder
19. september 2004 - 18:22 #8
sorry.... det er nogle gange ikke så let at vide hvad udgangspunktet er når folk skriver her... det var bestemt ikke for at være nedladende.

Det nemmeste vil nok være hvis du laver en specialisering baseret på ControlCollection.
Avatar billede snepnet Nybegynder
19. september 2004 - 18:30 #9
Hvis du gerne vil lidt videre end det, er der et par hints her:
http://samples.gotdotnet.com/quickstart/aspplus/doc/webctrlauthoring.aspx#parsing
Avatar billede davidfossil Nybegynder
19. september 2004 - 19:13 #10
ControlCollection tror jeg er det jeg har brug for.
Ved du om der findes en hurtig måde at fortælle den hvilke klasser der "passer ind" (i dette tilfælde alt hvad der nedaver fra HyperLink) ?
Avatar billede snepnet Nybegynder
19. september 2004 - 19:42 #11
undskyld ventetiden.... jeg bliver lige nødt til at ordne nogle ting. jeg er tilbage om en halv til en hel time.
Avatar billede snepnet Nybegynder
19. september 2004 - 21:06 #12
Ja - beklager.... der gik lige lidt tid.
Jeg har lavet et lille eksempel til dig... Måske kan du bruge det til noget.

Det er bare en custom-control der selv vedligeholder en typestærk liste, og implementerer IEnumerable, således at du kan bruge den på denne måde :

// opret et linkliste
SpecialLinkList linklist = new SpecialLinkList();

// smide nogle links ind i den
for(int i=0;i<10;i++)
{
    SpecialLink sl = new SpecialLink();
    sl.NavigateUrl="http://www.google.com";
    sl.Text = "LINK";
    linklist.AddLink(sl);
}

// smid linklisten ind på formen
Form1.Controls.Add(linklist);

// og løb den igennem med en foreach (det er den der kræver IEnumerable)
foreach(SpecialLink link in linklist)
{
    Response.Write("We got a SpecialLink<br>");
}
Avatar billede snepnet Nybegynder
19. september 2004 - 21:08 #13
Hele koden er som følger hvis du vil prøve det.

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace EXP2
{
    public class DavidFossil : System.Web.UI.Page
    {
        protected HtmlForm Form1;

        private void Page_Load(object sender, System.EventArgs e)
        {
            // opret et linkliste
            SpecialLinkList linklist = new SpecialLinkList();

            // smide nogle links ind i den
            for(int i=0;i<10;i++)
            {
                SpecialLink sl = new SpecialLink();
                sl.NavigateUrl="http://www.google.com";
                sl.Text = "LINK";
                linklist.AddLink(sl);
            }

            // smid linklisten ind på formen
            Form1.Controls.Add(linklist);

            // og løb den igennem med en foreach (det er den der kræver IEnumerable)
            foreach(SpecialLink link in linklist)
            {
                Response.Write("We got a SpecialLink<br>");
            }
        }

        override protected void OnInit(EventArgs e)
        {
            InitializeComponent();
            base.OnInit(e);
        }
       
        private void InitializeComponent()
        {   
            this.Load += new System.EventHandler(this.Page_Load);
        }
    }

    public class SpecialLink : HyperLink
    {
        public override void RenderBeginTag(HtmlTextWriter writer)
        {
            writer.AddAttribute(HtmlTextWriterAttribute.Title, "What a title");
            base.RenderBeginTag (writer);
        }

        public override void RenderEndTag(HtmlTextWriter writer)
        {
            base.RenderEndTag (writer);
        }
    }


    public class SpecialLinkList : Control, IEnumerable
    {
        private SpecialLinkCollection _items = new SpecialLinkCollection();

        public SpecialLinkCollection Items
        {
            get{return _items;}
        }

        public int AddLink(SpecialLink specialLink)
        {
            return _items.Add(specialLink);
        }

        protected override void Render(HtmlTextWriter writer)
        {
            foreach(SpecialLink sl in _items)
            {
                sl.RenderControl(writer);
                writer.WriteFullBeginTag("BR");
            }
            base.Render (writer);
        }

        public IEnumerator GetEnumerator()
        {
            // TODO:  Add SpecialLinkList.GetEnumerator implementation
            return Items.GetEnumerator();
        }
    }   

    public class SpecialLinkCollection : CollectionBase
    {
        public SpecialLink this[int index]
        {
            get{return (SpecialLink)List[index];}
            set{List[index] = value;}
        }

        public int Add(SpecialLink value)
        {
            return List.Add(value);
        }

        public int IndexOfSpecialLink(SpecialLink value) 
        {
            return(List.IndexOf(value));
        }

        public void Insert(int index, SpecialLink value ) 
        {
            List.Insert(index, value);
        }

        public void Remove(SpecialLink value) 
        {
            List.Remove(value );
        }

        public bool Contains(SpecialLink value) 
        {
            return(List.Contains(value));
        }

        protected override void OnInsert(int index, Object value) 
        {
            if (!(value is SpecialLink))
                throw new ArgumentException("value must be of type SpecialLink.", "value" );
        }

        protected override void OnRemove( int index, Object value ) 
        {
            if (!(value is SpecialLink))
                throw new ArgumentException( "value must be of type SpecialLink.", "value" );
        }

        protected override void OnSet( int index, Object oldValue, Object newValue ) 
        {
            if (!(newValue is SpecialLink))
                throw new ArgumentException( "newValue must be of type SpecialLink.", "newValue" );
        }

        protected override void OnValidate( Object value ) 
        {
            if (!(value is SpecialLink))
                throw new ArgumentException( "value must be of type SpecialLink." );
        }
    }
}
Avatar billede snepnet Nybegynder
19. september 2004 - 21:10 #14
linket er ikke så specielt endda :o) det propper bare et ligegyldigt tooltip ind.

hvis du vil kunne opbygge kontrollen deklerativt i aspx-koden bliver du nødt til at lave din egen ControlBuilder... du må sige til hvis jeg skal putte det med i eksemplet.

håber det var lidt i den stil du var ude efter.....

mvh
Avatar billede davidfossil Nybegynder
20. september 2004 - 08:29 #15
Mange tak for hjælpen, jeg tror jeg klarer den der fra :o)

Vil du skrive et svar så jeg kan give dig nogle point?
Avatar billede snepnet Nybegynder
20. september 2004 - 08:43 #16
jepper :o)
du siger til hvis der er noget.... det der med at få det til at virke deklerativt kan gøre drille en smule. altså hvis du vil kunne sådan noget her (opbygget i designeren) :

<cc1:SpecialLinkList id="sll1" runat="server">
  <cc1:SpecialLink id="sl1" runat="server" navigateurl="http://www.google.dk">LINK</asp:SpecialLink>
  <cc1:SpecialLink id="sl1" runat="server" navigateurl="http://www.google.dk">LINK</asp:SpecialLink>
  <cc1:SpecialLink id="sl1" runat="server" navigateurl="http://www.google.dk">LINK</asp:SpecialLink>
</cc1:SpecialLinkLisk>

mvh
Avatar billede davidfossil Nybegynder
20. september 2004 - 09:46 #17
D
Avatar billede davidfossil Nybegynder
20. september 2004 - 09:48 #18
Ingen problemer, det har jeg fået til at virke som det skal.
Skriver den dog så den ligner mere dette:

<jsr:LinkList Header="Gode links" Runat="server">
  <Links>
    <jsr:HyperLink NavigateUrl="blabla.html">Link</jsr:HyperLink>
    <jsr:HyperLink NavigateUrl="blabla.html">Link</jsr:HyperLink>
    <jsr:HyperLink NavigateUrl="blabla.html">Link</jsr:HyperLink>
  </Links>
</jsr:LinkList>
Avatar billede snepnet Nybegynder
20. september 2004 - 16:04 #19
alletiders :o)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester