Toon posts:

[C#/ASP.NET] Dynamic Event Handling*

Pagina: 1
Acties:

Verwijderd

Topicstarter
Volgens mij is het een niet al te lastig probleem maar ik kan er maar geen logica in vinden.

Wil ik een event op kunnen vangen van een dynamische control dan MOET deze control in de init fase bestaan? Tenminste, dit is de enige manier waarop ik dit voor elkaar kan krijgen.

Stel dat er echter een event optreed die de datasource van de betreffende control veranderd, dan heb ik dus een probleem, want de control is al in de init fase aangemaakt in de oude staat om eventuele events van deze control op te vangen. En het event waarbij de datasource van de betreffende control wordt gewijzigd treed pas na de load fase op. Op deze manier wordt er dus 2 keer gedatabind en dat lijkt me zeer overbodig.

Wat ik zo op internet heb kunnen vinden lijkt het mij dat ik de control dan aan de viewstate moet toevoegen zodat ik hem niet opnieuw hoef aan te maken in de init fase, en er toch events op kunnen treden van de betreffende control?

Vervolgens kan ik bij een eventueel event waarbij de datasource van de betreffende control gewijzigd wordt gewoon de datasource wijzigen, en bij een eventuele postback die niets met de betreffende control doet, zorgt de viewstate ervoor dat de control in de oude status blijft bestaan?

Kloppen mijn theorien hierover? of zit ik nou echt helemaal verkeerd te denken?
Sinds ik met asp.net aan de slag ben vind ik het wel een zeer fraaie manier om websites te bouwen, maar dit is toch een probleem waar ik al een aantal keer tegenaan gelopen ben, en het is me tot nog toe nog niet gelukt hier een mooie oplossing voor te vinden.

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 18:39

gorgi_19

Kruimeltjes zijn weer op :9

Je kant rustig events buiten je init toevoegen, zolang je te allen tijde maar je controlcollection op orde houdt. En viewstate houdt niets over de controls zelf bij, hooguit enkele waarden.

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Verwijderd

Topicstarter
Dus viewstate bied in dit geval geen oplossing?

Ik bedoelde eigenlijk niet het koppelen van events, dat is het probleem niet. Maar juist het opvangen wanneer de events op moeten treden. Ik heb bijvoorbeeld een dynamic control voor tabbladen, en het valt me op dat:
- NA de postback, het tabblad control uit de vorige pagina in de init aangemaakt moet zijn, anders treed het hele click event van de control niet op.

  • PhysicsRules
  • Registratie: Februari 2002
  • Laatst online: 31-03 07:26

PhysicsRules

Dux: Linux voor Eenden

De enige voorwaarde aan events is dat je de eventhandler aan het event koppelt voordat het event optreedt. Als je dus een event wilt koppelen aan een datasource dan moet je dat doen voordat een method met die datasource aan de slag gaat.

Let daarbij wel op: je kan in ASP.Net maar één keer een databind doen. De twee wordt gewoon genegeerd. Zoek op internet wat info op over de life-cycle van een ASP.Net pagina. Dat zal je sowieso helpen.

Verwijderd

Topicstarter
Ik zal hier nog even een klein voorbeeld van mijn probleem geven

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
53
54
55
56
public class Index : Page {
    public Panel TabSet; 
    public Panel SubTab;
    WCTabGroup SubTabs = new WCTabGroup();

    protected override void OnInit( EventArgs e ) {
        base.OnInit( e );

        WCTabGroup tabGroup = new WCTabGroup();
        tabGroup.DataSource = DataBase.ExecuteQuery(
            "SELECT tabset_name, tabset_id " +
            "FROM " + ConfigurationSettings.AppSettings["TablePrefix"] + "tabset " +
            "ORDER BY tabset_name ASC"
        );
        tabGroup.DataTextField = "tabset_name";
        tabGroup.DataValueField = "tabset_id";;
        tabGroup.DataBind();
        tabGroup.WCTabGroupChanged += new WCTabGroupCommandEventHandler( this.OnTabGroupChanged );
        TabSet.Controls.Add( tabGroup );
    }

    public void CreateSubTabs() {
        if ( HttpContext.Current.Session["SubTabGroup"] == null ) return;
        SubTabs.DataSource = DataBase.ExecuteQuery(
            "SELECT tab_name, tab_id " +
            "FROM " + ConfigurationSettings.AppSettings["TablePrefix"] + "tab " +
            "WHERE tab_tabset_id = " + HttpContext.Current.Session["SubTabGroup"] + " " +
            "AND tab_parent_id IS NULL " +
            "ORDER BY tab_name ASC"
        );
        SubTabs.DataTextField = "tab_name";
        SubTabs.DataValueField = "tab_id";  
        SubTabs.WCTabGroupChanged += new WCTabGroupCommandEventHandler( this.OnSubTabChanged ); 
        SubTabs.DataBind();
        SubTab.Controls.Add( SubTabs );     
    }

    public void OnTabGroupChanged( Object o, WCTabGroupCommandEventArgs e ) {
        HttpContext.Current.Session["SubTabGroup"] = e.Value;
    }

    public void OnSubTabChanged( Object o, WCTabGroupCommandEventArgs e ) {
        // doe iets...
    }

    protected override void OnLoad( EventArgs e ) {
        base.OnLoad( e );
        if ( !IsPostBack ) {
            HttpContext.Current.Session["SubTabGroup"] = null;
        }
    }

    protected override void OnPreRender( EventArgs e ) {
        if ( HttpContext.Current.Session["SubTabGroup"] != null ) CreateSubTabs();
    }
}


Zoals je misschien ziet worden de subtabs aangemaakt na een event van de hoofdtabs, dit gaat opzich goed, omdat de hoofdtabs toch altijd hetzelfde zijn en altijd op de pagina staan.

Nou is het eerste probleem dus: Hoe zorg ik dat die subtabs op de pagina blijven staan, mijn oplossing op dit moment is om de subtabs pas bij de prerender echt aan te maken, en dit omdat er eventueel events kunnen optreden die ervoor zorgen dat er een andere datasource aan de subtabs gekoppeld wordt. Ik weet dus pas in de prerender fase 100% zeker dat ik alle benodigde gegevens heb. Ik vraag me echter of of dit wel DE manier is dit aan te pakken. Want hieruit vloeit het probleem met events voort.

Omdat ik dus de subtabs pas in de prerender fase aanmaak, treden eventuele events van de subtabs niet op. Wanneer ik de subtabs echter in de init fase aanmaak, treden de events wel op, maar dit klopt dan dus niet omdat de subtabs bij een opkomend event gewijzigd kunnen worden.

Volgens mij is dus mijn pagina opbouw niet helemaal goed, ik snap opzich ook wel waar het fout gaat. Maar hoe ik het op kan lossen... ?

  • Alex
  • Registratie: Juli 2001
  • Laatst online: 10-11 17:17
Totaal offtopic, maar heb je ooit van SQL Injections gehoord? Ik denk dat ik binnen no-time je database leeg kan trekken als ik zie hoe je je queries concat...

Deze post is bestemd voor hen die een tegenwoordige tijd kunnen onderscheiden van een toekomstige halfvoorwaardelijke bepaalde subinverte plagiale aanvoegend intentioneel verleden tijd.
- Giphart


Verwijderd

Topicstarter
Hm, kan ik me wel iets bij voorstellen ja, je bedoeld dat je de session data kan wijzigen in sql waardoor je dus inderdaad sql in de bestaande query kan stoppen?

[ Voor 46% gewijzigd door Verwijderd op 07-12-2006 17:03 ]


Verwijderd

Het probleem dat hier optreedt is vrij eenvoudig te verklaren en is naar mijn idee een tekortkoming in het pagina en event model van ASP.NET. Jij geeft voor je tabbladen aan welk event er op moet treden als je een ander tabblad aanklikt, maar om dat event uit te voeren moet er opnieuw een request worden gedaan. Daarom wordt je pagina eerst herladen. Als je vervolgens je tabbladen niet aanmaakt na de reload, dan kan ook niet achterhaald worden welk tabblad je hebt aangeklikt. Precies op dit punt zou naar mijn idee asp.net verbeter moeten worden, want door de postback moet toch op een of andere manier bekend zijn voor asp.net welk control de postback heeft veroorzaakt.

Om je probleem op te lossen, zou je gebruik kunnen maken van een vieze oplossing. Namelijk een hidden inputveld. Op het moment dat je een tabblad aanklikt, zet je met javascript de waarde van dat veld en zorg je dat de pagina herlaad. Dan lees je het veld uit en kan je afhankelijk daarvan andere tabbladen laten zien.

werken met "HttpContext.Current.Session["SubTabGroup"]" heeft overigen dus geen zin. want je event wordt normaal gesproken al na de reload uitgevoerd. Dus kan je het gewoon in een variabele in je pagina laten. (probeer sessie-variable te vermijden)

[ Voor 11% gewijzigd door Verwijderd op 07-12-2006 19:39 ]


Verwijderd

Topicstarter
Hm, dat maakt ASP.NET inderdaad wel een stukje minder fraai als hier geen standaard oplossingen voor zijn. Ik zal het eens proberen met een hidden input field zoals je zei.

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 18:39

gorgi_19

Kruimeltjes zijn weer op :9

Als je tabbladen aanmaakt, waarom werk je dan niet met GET ipv postbacks? Verder ben ik benieuwd hoe je zou moeten weten welke control een postback heeft veroorzaakt; HTTP is immers stateless; je kan geen state bijhouden. Bijhouden in Sessions? Dan blaas je binnen notime je geheugen op.

Meesturen in Viewstate? Ding is al redelijk groot, om dan ook alle controls mee te gaan serializen. Verder creeer je dan een nieuw securityprobleem; clientside is immers bekend welke methods aangesproken gaan worden.

Verder zie ik niet in waarom je data moet vullen in de Init; imho kan alles geladen worden in de load (met controle op een postback). De viewstate van de listcontrol hoort er voor te zorgen dat de items geladen worden. PreRender is sowieso te laat om je controlcollection te veranderen.

[ Voor 96% gewijzigd door gorgi_19 op 08-12-2006 10:54 ]

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Verwijderd

Topicstarter
Nou je het zegt, via de GET zullen de waardes neem ik aan wel gewoon al in de init beschikbaar zijn dus in dat geval is dat inderdaad de meest eenvoudige oplossing, en dan hoef ik geen input fields met javascript te vullen. Dat eerst maar es doen dan.

Als ik nou met de GET werk dan is het inderdaad ook niet van belang de controls in de init aan te maken. Dit was omdat ik anders geen events van de controls kan opvangen, maar als ik het toch via de GET oplos dan maakt dit inderdaad niet uit.

Alleen:
De viewstate van de listcontrol hoort er voor te zorgen dat de items geladen worden.
Snap ik even niet helemaal?

[ Voor 43% gewijzigd door Verwijderd op 08-12-2006 11:00 ]


  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 18:39

gorgi_19

Kruimeltjes zijn weer op :9

Verwijderd schreef op vrijdag 08 december 2006 @ 10:55:
Als ik nou met de GET werk dan is het inderdaad ook niet van belang de controls in de init aan te maken. Dit was omdat ik anders geen events van de controls kan opvangen, maar als ik het toch via de GET oplos dan maakt dit inderdaad niet uit.
Als je met dynamische controls gaat werken, is het niet verkeerd om een beetje die stijl aan te leren :)
Alleen:

[...]

Snap ik even niet helemaal?
Geladen blijven, de waarden behouden blijven tijdens een postback :)

[ Voor 28% gewijzigd door gorgi_19 op 08-12-2006 11:05 ]

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Verwijderd

Topicstarter
Ok, volgens mij begin ik het te snappen :) .

Aangezien ik eigenlijk van plan was om zo'n beetje de hele site met dynamische controls te maken, zal ik toch maar even flink gebruik gaan maken van de GET.

Bedankt voor de hulp.

Verwijderd

gorgi_19 schreef op vrijdag 08 december 2006 @ 10:47:
Meesturen in Viewstate? Ding is al redelijk groot, om dan ook alle controls mee te gaan serializen. Verder creeer je dan een nieuw securityprobleem; clientside is immers bekend welke methods aangesproken gaan worden.
Ooit onderzocht wat er precies in je viewstate zit als je hem decode?
Overigens wordt voor de postback aan javascript funtie aangeroepem die ik iets als een control-id meegeeft.

GET-variabelen zou hier wel een goede oplossing zijn trouwens.

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 18:39

gorgi_19

Kruimeltjes zijn weer op :9

Verwijderd schreef op vrijdag 08 december 2006 @ 11:15:
[...]


Ooit onderzocht wat er precies in je viewstate zit als je hem decode?
Overigens wordt voor de postback aan javascript funtie aangeroepem die ik iets als een control-id meegeeft.
Als je tijdens een postback je controlcollection overhoop gooit, kijkt hij naar de nieuwe situatie :) Als je bijvoorbeeld buttons gaat toevoegen tijdens een postback, wordt dat in een aantal gevallen niet gedetecteerd in je viewstate (en krijg je hier dus geen exceptions over) en gaat hij naar de nieuwe situatie over :)

Als .Net echt wat ging doen met die waarden, dan zou je zelf je controlcollection niet meer op orde hoeven te brengen :)

Digitaal onderwijsmateriaal, leermateriaal voor hbo

Pagina: 1