[ASP.NET] Button op WebUserControl werkt niet.

Pagina: 1
Acties:

  • JaymzHetfield
  • Registratie: Februari 2001
  • Laatst online: 18-07 21:06
Ik ben een beetje bezig met Web User Controls in ASP.NET. Mijn Web User Control heeft 1 button. Sleep ik deze Control in een nieuwe webform en probeer ik deze uit, dan werkt het prima... de events van het clicken op de Button komen gewoon binnen en er gebeurt wat er moet gebeuren zodra er geclickt wordt.

Maar aangezien het me wel leuk leek als ik niet bij elke pagina die ik maak die Control erin zou hoeven te slepen, besloot ik mijn eigen MyPage class te maken. De class MyPage is afgeleid van System.Web.UI.Page.

In deze class wordt de Web User Control als volgt toegevoegd:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
   // Get a reference to the form control
   Control form = Page.Controls[1];

   MyWebControl wc;
   wc = (MyWebControl) LoadControl(Request.ApplicationPath 
               + Path.AltDirectorySeparatorChar + "MyWebControl.ascx");
   form.Controls.AddAt(0, wc);

   // Render as usual
   base.Render(writer);
}


Het idee is dat bij elke Webform in mijn webapp nu in de codebehind file aangegeven wordt dat ie van MyPage is afgeleid i.p.v. de gebruikelijke System.Web.UI.Page. Dit had ik ergens in een voorbeeldje gezien en leek me wel handig omdat je op die manier bij het maken van je webforms alleen op de inhoud hoeft te richten en niet telkens alle user controls toe hoeft te voegen.

Maar het probleem is:
Dezelfde WebUserControl waarvan de button events eerst dus netjes verwerkt werden, werkt nu niet meer. Je kan klikken op die button wat je wil maar er gebeurt niks. Als ik dezelfde user control in een webform sleept, dan werkt de button erop dus wel.

edit:
Even de layout hersteld
en heb maar aangenomen dat dit C# is ;)

[ Voor 5% gewijzigd door drm op 11-04-2003 15:06 ]

Metal up your ass


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

alley

ahuh

Je voegt de button toe in het render-event.. dit is een van de laatste events die getriggered word... Als jou button-click event dus wordt aangeroepen, bestaat je button nog niet eens.

Je kunt sub-controls het beste toeveogen in het Init-event

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


  • JaymzHetfield
  • Registratie: Februari 2001
  • Laatst online: 18-07 21:06
Ik zal het eens even uitproberen.

Metal up your ass


  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 20-08 11:40

gorgi_19

Kruimeltjes zijn weer op :9

alley schreef op 11 april 2003 @ 18:12:
Je voegt de button toe in het render-event.. dit is een van de laatste events die getriggered word... Als jou button-click event dus wordt aangeroepen, bestaat je button nog niet eens.

Je kunt sub-controls het beste toeveogen in het Init-event
Puur voor mijn begrip.. Waarom het init event? Waarom override je de CreateChildControls niet?

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • JaymzHetfield
  • Registratie: Februari 2001
  • Laatst online: 18-07 21:06
Is CreateChildControls een nettere plek om dat te doen?

Metal up your ass


  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 20-08 11:40

gorgi_19

Kruimeltjes zijn weer op :9

JaymzHetfield schreef op 14 april 2003 @ 17:18:
Is CreateChildControls een nettere plek om dat te doen?
Voor zover ik weet wel.. Daarom was ik ook zo benieuwd naar de reden van de Init.

Digitaal onderwijsmateriaal, leermateriaal voor hbo


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

alley

ahuh

Hmm, ik weet niet precies wanneer createchildcontrols wordt aangeroepen, zul je ff op moeten zoeken, maar voor mijn gevoel gebruik ik toch liever een event dan dat ik een functie moet overriden.... Als het beiden werkt, zou ik toch kiezen voor een event...
(Om een OT conversatie te voorkomen: ik ben niet TEGEN overrides ofzo... ik geef alleen de voorkeur aan events als de keuze voorhanden is)

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


  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 20-08 11:40

gorgi_19

Kruimeltjes zijn weer op :9

Volgens mij kwam je dan in de knoei met je viewstate dat deze nog niet bereikbaar is.. Zodra ik tijd heb, zal ik eens kijken of ik eea kan testen.

Zie mede ook over het Init-event:
Server controls should perform any initialization steps that are required to create and set up an instance. You cannot use view-state information within this event; it is not populated yet. You should not access another server control during this event, regardless of whether it is a child or parent to this control. Other server controls are not certain to be created and ready for access.

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • JaymzHetfield
  • Registratie: Februari 2001
  • Laatst online: 18-07 21:06
Ik ben er nog niet helemaal uit geloof ik. Door de user controls toe te voegen in:
override protected void CreateChildControls()
of
override protected void OnInit(EventArgs e)
werken de buttons op de ene user control wel, maar die op de andere niet.

Ik zal even uit leggen hoe het zit. De volgende onderdelen spelen een rol:

1. BovensteUserControl:
Deze bevat een tabel met 8 cellen. Zowel voor de tabel als voor de td's staat "run as server control" aan, zodat tijdens runtime de kleuren nog veranderd kunnen worden of de tabel op visible=false gezet kan worden. Elke cel bevat 1 button die je naar een bepaald deel van de site moet brengen.

2. OndersteUserControl:
Deze bevat een tabel met 8 cellen. Zowel voor de tabel als voor de td's staat "run as server control" aan, zodat tijdens runtime de kleuren nog veranderd kunnen worden of de tabel op visible=false gezet kan worden. Elke cel bevat 1 button die je naar een bepaald deel van de site moet brengen. In tegenstelling tot BovensteUserControl staan de teksten op de buttons en de url's waar ze heen moeten leiden niet vast. De inhoud van OndersteUserControl moet namelijk afhankelijk zijn van wat je aangeklikt heb in de BovensteUserControl.

3. BasePage:
Dit is een superclass (in C# heet dat geloof ik baseclass). Alle andere pagina's zijn hier van afgeleid. Het definieert 2 strings: moduleNaam en subModuleNaam welke respectievelijk de gekozen knop in de Bovenste- en OndersteUserControl voorstellen. In de BasePage worden in override protected void CreateChildControls() de 2 user controls gemaakt, dat gaat zo:
code:
1
2
3
4
5
6
7
8
9
BovensteUserControl bovenste = (SWModuleHeader) LoadControl(Request.ApplicationPath
 + Path.AltDirectorySeparatorChar + "Controls/BovensteUserControl.ascx");
bovenste.selectModule(moduleNaam);
form.Controls.AddAt(0,bovenste);

OndersteUserControl onderste = (SWSubModuleHeader) LoadControl(Request.ApplicationPath
 + Path.AltDirectorySeparatorChar + "Controls/OndersteUserControl.ascx");
onderste.selectModule(moduleNaam, subModuleNaam);
form.Controls.AddAt(1,onderste);


Zoals je ziet hebben beide usercontrols een functie genaamd selectModule. Bij BovensteUserControl krijgt deze als parameter de moduleNaam. Deze wordt dan gebruikt om de juiste cell van een kleur te voorzien. Bij OndersteUserControl krijgt deze als parameters de moduleNaam en subModuleNaam mee. De moduleNaam wordt dan gebruikt om te bepalen welke teksten er op de knoppen moeten komen te staan en welke url's er bij de knoppen horen. De subModuleNaam wordt gebruikt om de juiste cell van de OndersteUserControl te kleuren.

4. PaginaX
Deze is afgeleid van BasePage en krijgt dus automatisch de juiste user controls bovenaan de pagina. Deze pagina doet:
code:
1
2
3
4
5
private void Page_Load(object sender, System.EventArgs e)
{
   base.moduleNaam="Auto";
   base.subModuleNaam="Geen";
}


5. PaginaY
Deze is ook afgeleid van BasePage en doet dit:
code:
1
2
3
4
5
private void Page_Load(object sender, System.EventArgs e)
{
   base.moduleNaam="Auto";
   base.subModuleNaam="Ferrari";
}


In dit voorbeeld is het dus de bedoeling dat als je PaginaX opent dat je dan beide user controls ziet waarbij in de bovenste "Auto" een gehighlighte kleur heeft. Dat daaronder in de 2e user control alle bij "Auto" horende knopper staan zoals "Lada", "Ferrari" etc. maar dat er daar nog geen van is gekleurd.
Als je PaginaY opent dan moet zowel "Auto" in de bovenste user control als "Ferrari" in de onderste gekleurd zijn.

Dat was even om de situatie te verduidelijken en dan nu het probleem:

*****HET PROBLEEM*****

Klik ik in de bovenste UserControl op een van de buttons dan gaat het goed, dit gebeurt er:
1. De pagina wordt gerefreshed o.i.d. (PostBack neem ik aan?) en de BasePage wordt aangeroepen. De waardes van moduleNaam en subModuleNaam zijn dan de waardes uit de BasePage en niet die van een van de daadwerkelijke pagina's. 8)7
2. Dan komt ie bij het clickevent aan en doet dus Server.Transfer
3. Dan wordt de BasePage klasse nogmaals aangeroepen, maar nu hebben de strings wel de juiste waardes van de pagina waar naartoe getransferred worden.
4. Geslaagd.

Echter:
Heb ik PaginaX voor mijn neus en klik ik in de onderste user control op "Ferrari", dan krijg ik PaginaY niet.

De button event ziet er zo uit:
code:
1
2
3
4
private void btn2_Click(object sender, System.EventArgs e)
{
    Server.Transfer(btn2URL);
}

btn2URL is een string die een waarde krijgt afhankelijk van de gekozen module. De grap is alleen dat ie nooit bij deze eventhandler aankomt. Klik ik op de knop dan gebeurt er namelijk het volgende:

1. De pagina wordt gerefreshed o.i.d. (PostBack neem ik aan?) en de BasePage wordt aangeroepen. De waardes van moduleNaam en subModuleNaam zijn dan de waardes uit de BasePage en niet die van een van de daadwerkelijke pagina's. 8)7 2. Gevolg: subModuleNaam niet bekend bij selectModule() in de onderste UserControl, gevolg: OndersteUserControl is niet meer hetzelfde.
3. Afgelopen, komt niet bij button event.

Wie helpt?

[ Voor 7% gewijzigd door JaymzHetfield op 17-04-2003 11:12 . Reden: layout ontneukt ]

Metal up your ass


  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 20-08 11:40

gorgi_19

Kruimeltjes zijn weer op :9

Server.Transfer kan viewstatep porblemen opleveren, als ik me goed herinner. Je maakt dynamisch controls aan; deze wordt niet altijd automatisch geladen. Maak een method die het Load event handled en zet hierin, bij een postback: EnsureChildControls. Deze method zorgt er voor dat de child controls gemaakt zijn; zo niet, dan worden ze alsnog gemaakt.

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • tijn
  • Registratie: Februari 2000
  • Laatst online: 31-07 00:06
gorgi_19 schreef op 15 april 2003 @ 09:24:
Volgens mij kwam je dan in de knoei met je viewstate dat deze nog niet bereikbaar is.. Zodra ik tijd heb, zal ik eens kijken of ik eea kan testen.

Zie mede ook over het Init-event:


[...]
Wat zou je met de viewstate willen doen in het Init event? Als je er maar voor zorgt dat de controls structuur netjes opgebouwd wordt (incl. evt usercontrols die je wilt inladen) kunnen deze controls daarna ook hun viewstate weer terughalen en werken alle events zo als ze horen te doen.

Cuyahoga .NET website framework


  • JaymzHetfield
  • Registratie: Februari 2001
  • Laatst online: 18-07 21:06
gorgi_19 schreef op 17 April 2003 @ 13:05:
Server.Transfer kan viewstatep porblemen opleveren, als ik me goed herinner.
Wat kan ik dan beter gebruiken voor de events van de buttons in de User Controls? Response.Redirect neem ik aan?
Je maakt dynamisch controls aan; deze wordt niet altijd automatisch geladen. Maak een method die het Load event handled en zet hierin, bij een postback: EnsureChildControls. Deze method zorgt er voor dat de child controls gemaakt zijn; zo niet, dan worden ze alsnog gemaakt.
Ik neem aan dat je zoiets bedoelt?:
code:
1
2
3
4
5
6
private void Page_Load(object sender, System.EventArgs e)
{
    if(Page.IsPostBack)
    this.EnsureChildControls();

}

En die plaats ik dan in de BasePage class? Zo ja, dan helpt dat niet. Of bedoelde je ergens anders?

Even nog een hint: Als ik een asp:HyperLink gebruik ipv een asp:button, dan werkt het wel. Je krijgt dan niet eerst die postback waarin de waardes uit de baseclass verschijnen, en dan gaat het dus goed. Ik wil echter geen asp:HyperLink gebruiken.

Metal up your ass


  • JaymzHetfield
  • Registratie: Februari 2001
  • Laatst online: 18-07 21:06
En trouwens, zo dynamisch is OndersteUserControl toch niet? Hij bestaan altijd uit dezelfde knoppen btn1 t/m btn8. Het enige dat per pagina anders is, zijn de teksten op de buttons en de waardes van de strings btn1URL t/m btn8URL waarheen verwezen wordt zodra er op de debetreffende button geklikt wordt (althans, dat was de bedoeling, hij komt echter nooit bij dat clickevent).

Metal up your ass


  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 20-08 11:40

gorgi_19

Kruimeltjes zijn weer op :9

JaymzHetfield schreef op 17 April 2003 @ 16:14:
En trouwens, zo dynamisch is OndersteUserControl toch niet? Hij bestaan altijd uit dezelfde knoppen btn1 t/m btn8. Het enige dat per pagina anders is, zijn de teksten op de buttons en de waardes van de strings btn1URL t/m btn8URL waarheen verwezen wordt zodra er op de debetreffende button geklikt wordt (althans, dat was de bedoeling, hij komt echter nooit bij dat clickevent).
* gorgi_19 moet lezen en z'n hersensgebruiken.. |:( |:(

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • JaymzHetfield
  • Registratie: Februari 2001
  • Laatst online: 18-07 21:06
Het zij je vergeven ;) Maar heb je misschien nog suggesties?

Metal up your ass


  • JaymzHetfield
  • Registratie: Februari 2001
  • Laatst online: 18-07 21:06
Om het (hopelijk) iets duidelijker te maken, heb ik het probleem in een soort sampletje gestopt bestaande uit een paar paginatjes. De source zit in een zipje en vind je hier: http://home.wanadoo.nl/jaymz/NET/UCTest.zip

Samengevat is het probleem hierbij:
1. Ik start Cars.aspx
2. Ik click op btn1 in de SubmoduleControl.
3. Er treedt een postback op.
4. CreateChildControls wordt opnieuw aangeroepen.
5. setText() wordt aangeroepen met null als parameter.
6. url1 = null
7. Response.Redirect mislukt.

[ Voor 9% gewijzigd door JaymzHetfield op 18-04-2003 17:12 ]

Metal up your ass


  • JaymzHetfield
  • Registratie: Februari 2001
  • Laatst online: 18-07 21:06
Niemand??

Ik weet vrij zeker dat het ligt aan het (verkeerde) gebruik van de MyPage base class waar alle andere pagina's afgeleides van zijn. Ik heb nu een nieuwe webform toegevoegd welke een DataList toont. De SelectedIndexChanged events komen echter nooit aan. Als ik de pagina niet afleid van MyPage maar gewoon van System.Web.UI.Page, dan werkt het wel. Het probleem zit 'm dus in het gebruik van de klasse MyPage. Ik kom er alleen niet achter wat het probleem is, ik kan ook nergens een vergelijkbaar probleem vinden...

Metal up your ass

Pagina: 1