Avatar billede dj_uncas Nybegynder
26. marts 2005 - 22:47 Der er 44 kommentarer og
1 løsning

usercontrol og placeholder i codebehind

Hejsa

Jeg har en codebehind-fil hvori jeg blandt andet har en pageNav klasse der har en metod der skal hente en usercontrol ind i en placeholder. Koden ser således ud:

public class PageNav
{
  public string page;
  public PlaceHolder phIndhold;
  public string getPage(string id)
  {
    if (id == null)
    {
        page = "default";
    }
    Control content = LoadControl("/it/pages/" + page + ".ascx");
    phIndhold.Controls.Add(content);
    }
}

Det hele ligger inde i et namespace "standard".

Nu prøver jeg så at kompilere .cs om til .dll, og får følgende fejl: "The name 'LoadControl' does not exist in the class or namespace standard.pageNav"

Hvad er det der går galt?? Jeg har ledt som en sindssyg i .NET klasse biblioteket, men har ikke fundet noget!
Avatar billede basementjack Nybegynder
27. marts 2005 - 00:09 #1
LoadControl er en metode fra TempleControl, som ligger i System.Web.UI.
Så du skal have en using på.

namespace standart.pageNav
{
using System.Web.UI;
....
}
Avatar billede dj_uncas Nybegynder
27. marts 2005 - 00:13 #2
det er netop det der er det underlige. Jeg har i starten af dokumentet:

using System;
using System.Web.UI;
osv. med en masse andre....

namespace standard
{
    //kode
}

Jeg kan ikke forstå det, medmindre jeg skal bruge vendingen "TemplateControl" et eller andet sted..
Avatar billede basementjack Nybegynder
27. marts 2005 - 00:17 #3
Så skulle det virke.... Tror ikke det har en forskel, men jeg gør det altid sådan her:

phIndhold.Controls.Add(LoadControl("/it/pages/" + page + ".ascx"));

Fejler det også, med samme fejl?..
Avatar billede dj_uncas Nybegynder
27. marts 2005 - 00:46 #4
samme fejl...
Avatar billede snepnet Nybegynder
27. marts 2005 - 00:53 #5
du må specialisere din klasse fra TemplateControl eller en klasse der er en specialisering af den, hvis du vil kunne LoadControl på den måde du har angivet. i dit tilfælde virker det mest nærliggende at du basere din komponent på en UserControl, og din klasse ville så komme til at se sådan her ud :

public class PageNav : UserControl

mvh
Avatar billede basementjack Nybegynder
27. marts 2005 - 00:56 #6
Godt set.. ;)

Så det bliver:

namespace xxx.xxx
{
    using System;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    public class PageNav : UserControl
    {
        public string page;
        public PlaceHolder phIndhold;
        public void getPage(string id)
        {
            if (id == null)
            {
                page = "default";
            }
            Control content = LoadControl("/it/pages/" + page + ".ascx");
            phIndhold.Controls.Add(content);
        }
    }
}
Avatar billede basementjack Nybegynder
27. marts 2005 - 01:32 #7
i :

        public void getPage(string id)
        {
            if (id == null)
            {
                page = "default";
            }
            Control content = LoadControl("/it/pages/" + page + ".ascx");
            phIndhold.Controls.Add(content);
        }

Hvorfor checker du for om id er null... Hvis du har givet en null string til getPage, har den fejlet inden den når så langt, skulle jeg mene.. Hvis det er for at se om den er tom eller ej, kan du prøve med if (id=="") istedet.
Avatar billede burningice Nybegynder
27. marts 2005 - 12:17 #8
basementjack>> Hvorfor skulle den have fejlet inden den når så langt? Det er helt validt at tjekke for null, og da også en meget god idé. At tjekke for String.Empty er også godt. Dog har jeg lidt svært ved at se hvorfor at id aldrig bliver brugt til noget i metoden. mon ikke det burde være sådan her:

public void getPage(string page)
        {
            if (page == null) page = "default";
            if (page == String.Emtpy) page = "default";

            Control content = this.LoadControl("/it/pages/" + page + ".ascx");
            if (content == null) throw new Exception(String.Format("Control {0} not found", page);
            phIndhold.Controls.Add(content);
        }
Avatar billede basementjack Nybegynder
27. marts 2005 - 15:04 #9
Hvis jeg et andet sted i koden kalder med :

string myId = null;
getPage(myID);

Så forventer jeg en fejl i det, at getPage skal have en string og den string der bliver givet er null. Så bør den da lave en NullReferenceException.

Ville jo så mene man skal checke for null før man kalder:

string myId = null;
if (my!=null)
{
  getPage(myID);
}

Am I wrong... Again?..
Avatar billede burningice Nybegynder
27. marts 2005 - 15:14 #10
det kommer helt an på ens design. Sådan som dj_uncas har gjort det, returneres default.ascx hvis at id er null. Det bør bare stå i ens dokumentation hvordan ens funktiom opfører sig ved null som argument.

En anden mulighed er jo

public void getPage(string id) {
    if (id == null) throw new ArgumentException("Id cannot be null");
}

og så have en try-catch om sit kald:

string id = null;
try {
  getPage(id);
} catch(ArgumentException) {
  // Der var noget galt med argumentet
}
Avatar billede snepnet Nybegynder
27. marts 2005 - 15:16 #11
og lige "for the record" - du får ingen fejl ved at kalde en metode der tager en string som parameter med null, med mindre du selv hæver fejlen - eller har anden kode i funktionen der forudsætter at parameteren ikke er null.
mvh
Avatar billede basementjack Nybegynder
27. marts 2005 - 15:33 #12
Godt, så blev det sat på plads. :)
Avatar billede dj_uncas Nybegynder
27. marts 2005 - 15:43 #13
grunden til id er at min kode skal loade en usercontrol udfra hvad der står i querystringen "id". Dvs. i default.aspx står der: getPage(Request.QueryString["id"]);

Anyways, det fik da ordnet den fejl! Nu dukker der så en anden op:

"standard.pageNav.getPage(string)": Not all code paths return a value.

Hvad er nu det?
Avatar billede snepnet Nybegynder
27. marts 2005 - 15:46 #14
public string getPage(string id) angiver at metoden skal returnere en string... fejlen kommer fordi det kan ske at der ikke returneres en sådan.
mvh
Avatar billede snepnet Nybegynder
27. marts 2005 - 15:47 #15
hvis den ikke skal returnere noget skal du angive den sådan her :

public void getPage(string id)

mvh
Avatar billede dj_uncas Nybegynder
29. marts 2005 - 16:10 #16
Ja, nu virker det.. Den burde jeg selv have set, men nogen gange er det nødvendigt med andre øjne vel :D
Avatar billede burningice Nybegynder
29. marts 2005 - 19:08 #17
man kan ikke se skoven for bare træer ;)
Avatar billede dj_uncas Nybegynder
31. marts 2005 - 17:30 #18
der var jeg vist lidt for hurtig! Nu fik jeg da kompileret det fint, men når jeg skal kalde funktionen getPage fra default.aspx går det galt. Jeg gør således:

string page = Request.QueryString["page"];
PageNav.getPage(page);

Fejlen:
An object reference is required for the nonstatic field, method, or property 'standard.PageNav.getPage(string)'
Avatar billede snepnet Nybegynder
31. marts 2005 - 18:31 #19
hvis metoden ikke er static skal du have en instans af klassen :

PageNav instans = new PageNav();

mvh
Avatar billede dj_uncas Nybegynder
31. marts 2005 - 19:14 #20
jep, det har jeg prøvet, men det kan den heller ikke lide..

//Kode:
string page = Request.QueryString["side"];
PageNav instans = new PageNav();
instans.getPage(page);

//Fejl:
System.NullReferenceException: Objektreferencen er ikke indstillet til en forekomst af et objekt.
Avatar billede burningice Nybegynder
31. marts 2005 - 19:46 #21
hvordan ser din getPage-funktion nu ud? Det lader til at der bliver sendt null med som parameter, men det tager du ikke højde for i funktionen
Avatar billede dj_uncas Nybegynder
04. april 2005 - 15:46 #22
Den ser således ud:

public void getPage(string id)
{
    if (id == null)
    {
        page = "default";
    }
    phIndhold.Controls.Add(LoadControl("/it/pages/" + page + ".ascx"));
}
Avatar billede burningice Nybegynder
04. april 2005 - 15:51 #23
du bør sikre dig at LoadControl rent faktisk returnere noget

public void getPage(string id)
{
    if (id == null)
    {
        page = "default";
    }
   
    Control c = LoadControl("/it/pages/" + page + ".ascx");
    if (c == null) // den ønskede control blev ikke fundet
    else phIndhold.Controls.Add(c);
}
Avatar billede burningice Nybegynder
04. april 2005 - 15:53 #24
mig bekendt returnere Request.QueryString["side"] aldrig null, men en tom streng hvis den ønskede querystring ikke findes. Så du bør også tjekke efter String.Emtpty

public void getPage(string id)
{
    if (id == null) id = "default";
    if (id == String.Emtpy) id = "default";
 
    Control c = LoadControl("/it/pages/" + id + ".ascx");
    if (c == null) // den ønskede control blev ikke fundet
    else phIndhold.Controls.Add(c);
}
Avatar billede basementjack Nybegynder
05. april 2005 - 10:12 #25
Mig bekendt vil LoadControl(...) da give en fejl, såfremt at den angivede fil ikke findes..
Avatar billede dj_uncas Nybegynder
05. april 2005 - 13:31 #26
Hmm, Det virker stadig ikke.. Nu får jeg dog en anden fejl:

An object reference is required for the nonstatic field, method, or property 'standard.PageNav.getPage(string)'

Jeg har direkte copy-pasted cyberfessors forslag, og har følgende i default.aspx:

void Page_Load()
{
  string page = Request.QueryString["page"];
  PageNav.getPage(page);
}
Avatar billede snepnet Nybegynder
05. april 2005 - 13:39 #27
hej dj ... det er samme problem som du spurgte til tidligere (31/03-2005 17:30:08)
mvh
Avatar billede burningice Nybegynder
05. april 2005 - 13:45 #28
LoadControl kommer ikke med nogen fejl, men returnerer bare null

og ja, husk at have en instans af objectet, du kan ikke udføre metoden direkte på klassen
Avatar billede dj_uncas Nybegynder
05. april 2005 - 14:48 #29
Nu synes jeg denne tråd er ved at køre i ring! Se min kommentar fra 31/03-2005 19:14:34.
Der fortæller jeg at jeg får en fejl når jeg forsøger at lave en instans af klassen.
Avatar billede snepnet Nybegynder
05. april 2005 - 15:14 #30
Du laver en instans af klassen med denne linie :
PageNav instans = new PageNav();
Og den tror jeg bestemt ikke giver dig en fejl.... Der var jo en fejl i selve GetPage-metoden, og hvis den er rette nu burde du kunne prøve igen.
Du kan under ingen omstændigheder kalde en metode der ikke er angivet som static - med mindre du laver en instans, hvilket du ikke gør her :

  string page = Request.QueryString["page"];
  PageNav.getPage(page);

Bare prøv sådan her :

  string page = Request.QueryString["page"];
  PageNav pn = new PageNav()
  pn.getPage(page);

mvh
Avatar billede dj_uncas Nybegynder
07. april 2005 - 14:54 #31
Yesh, det har jeg prøvet, men jeg får stadig denne fejl:

System.NullReferenceException: Object reference not set to an instance of an object.

Mangler der noget i klassen før jeg kan instasiere den? F.eks. en get/set ting?

Hvis i ikke har luret det endnu, er jeg ikke så skarp til alt det med OOP! Jeg kommer fra alm ASP, og prøver desperat at lære .NET
Avatar billede burningice Nybegynder
07. april 2005 - 23:32 #32
okay.. kan du se helt præcis hvad linjenr du får fejlen på, og kan du poste her hvad der står på den linje?
Avatar billede dj_uncas Nybegynder
08. april 2005 - 16:06 #33
Ok, fejlen ligger i linje 10 som er denne: pn.getPage(page);
Avatar billede snepnet Nybegynder
08. april 2005 - 17:16 #34
har du fået implementeret håndtering af page==null i getPage ?

egentlig kunne det være fint, hvis du postede hele koden som den ser ud nu... altså hele din page_load, og din klasse hvor du har getpage.... hvis din kode vedr. phContent stadig er den samme som det du postede først, vil phContent være null. så selvom alt går vel med at loade kontrollen og det hele, vil det stadig strande der.

en anden ting .... hvordan regner du med at få phContent til at dukke op på siden, hvis der bliver fyldt en usercontrol i ?

mvh
Avatar billede snepnet Nybegynder
08. april 2005 - 17:17 #35
bizard ... det var bestemt ikke meningen at det skulle have været et svar ?!? - jeg må have fumlet lidt rundt med et eller andet her - sorry.
mvh
Avatar billede dj_uncas Nybegynder
08. april 2005 - 17:19 #36
hovsa! Jeg kom til at acceptere dit svar.. Vi er ret gode til det med knapper osv. hva? Hmm, jeg håber du har et svar så :D
Avatar billede dj_uncas Nybegynder
08. april 2005 - 17:23 #37
nå, hele koden:

-------
bagved:
-------
namespace standard
{
    public class PageNav : Page
    {
        public string page;
        public PlaceHolder phIndhold;
        public void getPage(string id)
        {
            if (id == null)
            {
                page = "default";
            }
            phIndhold.Controls.Add(LoadControl("/it/pages/" + page + ".ascx"));
        }
    }
}

-------------
default.aspx:
-------------
void Page_Load()
{
  string page = Request.QueryString["page"];
  PageNav pn = new PageNav()
  pn.getPage(page);
}

på default.aspx er der desuden en <asp:placeholder id="phContent" runat="server" /> som usercontrollen skal lægges ned i.
Avatar billede snepnet Nybegynder
08. april 2005 - 17:28 #38
Sikken noget :o)
nå - jeg har oprettet et spm hvor du kan skrive hvordan point skal fordeles, så må vi kunne få ryddet op på den måde.
mvh
Avatar billede snepnet Nybegynder
08. april 2005 - 17:29 #39
Nå - men tilbage til spørgsmålet :o)

phIndhold bliver aldrig instantieret, så den vil altid være null, hvorved du vil få fejlen.

mvh
Avatar billede dj_uncas Nybegynder
08. april 2005 - 17:31 #40
dvs. jeg skal have noget som det her:

PlaceHolder phIndhold = new PlaceHolder i mit c# dok? Hvis ja, skal der så være en "public" ting foran? Jeg har endnu ikke helt styr på de forskellige referencer (public, private, protected osv.)
Avatar billede snepnet Nybegynder
08. april 2005 - 17:50 #41
ja - din placeholder skal instantieres inden du kan bruge den, men bortset fra det er der nogle ting jeg ikke helt forstår i det du har sendt.

hvis det er meningen at din default-side skal kunne indsætte en usercontrol i en given placeholder burde du bare lægge metoden i din page-klasse du har i forvejen i din codebehind for default.aspx.

hvis det er meningen at alle de sider du laver, skal kunne indsætte user controls baseret på et id - kan du sørge for at PageNav er den klasse du baserer alle dine sider på, således at du altså nedarver fra PageNav.
du bør så sørge for at du kan kalde metoden med en parameter som en den kontrol (placeholder) den loadede user control skal puttes ind i.

såhh.... jeg synes du skal starte med at lægge GetPage-metoden ind i den hvor din page_load ligger.
(så har du hverken problemer med at kalde LoadControl, og desuden vil du rent faktisk også kunne opnå at et eventuelt indhold i placeholderen vil blive vist på siden... hvilket ikke er tilfældet nu).

mvh
Avatar billede snepnet Nybegynder
08. april 2005 - 17:51 #42
(jeg bliver nødt til at smutte... og jeg er lidt nervøs for at nettet er gået kold derhjemme, så det kan tænkes at der går noget tid før jeg svarer igen)
Avatar billede snepnet Nybegynder
11. april 2005 - 22:41 #43
halløjsa - så er der net igen ;o)
hvordan går det her dj ?
mvh
Avatar billede dj_uncas Nybegynder
12. april 2005 - 13:29 #44
Tja, det virker når man bruger den page_load ide du nævner (08/04-2005 17:50:41), så det er den jeg vil fortsætte med.. Du kan vist give dig selv pointene, da det kun er dine forslag jeg rent faktisk har brugt til noget
Avatar billede snepnet Nybegynder
12. april 2005 - 13:34 #45
Jeg deler i porten med basementjack og fessoren her :
http://www.eksperten.dk/spm/607814
mvh
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