26. marts 2005 - 22:47Der 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!
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 :
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); } } }
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.
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); }
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 }
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
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.
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:
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); }
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.
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 :
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 ?
------- 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")); } } }
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.)
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).
(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)
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
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.