[C# WinForms] Events worden niet opnieuw getriggered

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Crazybyte
  • Registratie: Juli 2002
  • Laatst online: 02-09 15:23
In een applicatie die ik aan het maken ben zit het volgende form:

Afbeeldingslocatie: http://www.gaggia.org/dev/DrawingInfoForm_thumb.png
(Klik voor een grotere afbeelding)

Situatie:
Rechtsboven is een listView, in deze listView worden de revisies weergegeven die bekend zijn van een bepaalde tekening. Wanneer je een rij selecteerd in de listView worden de gegevens van die revisie opgehaald en getoond in de velden die op de diverse tabbladen staan.

Aan de controls op de tabbladen hangen events, bepaalde controls zijn namelijk enkel toegankelijk als je eerdere controls aangevinkt hebt. De controle hiervan gebeurd in de events. Voorbeeld: in de screenshot worden de textboxen voor partnumber en specification pas actief als je de checkbox FA aangevinkt hebt. Dit wordt geregeld in het event CheckedChanged van de checkbox FA.

Als het de eerste keer form geladen wordt en wanneer er een andere rij geselecteerd in de listView wordt, gebeurt er het volgende:
- Maak het form blanco en zet voor alle controls die niet vanaf het begin enabled moeten zijn, enabled op false.
- Laad de waardes behorende bij de geselecteerde rij in een locale variabele
- Laad het form met de gegevens die staan in de locale variabele

Bij het laden van het form worden alle events van de controls op de tabs ook doorlopen, waardoor dus uiteindelijk alle controls die een waarde hebben, gevuld worden en enabled worden. De rest blijft disabled.

Probleem:
Echter, wanneer je een andere rij selecteerd in de listView, worden deze events zo te zien niet aangeroepen.
Alle controls worden namelijk wel gevuld met de waardes die er zijn, maar de controls zelf blijven disabled.

Vraag:
Ik zou graag willen dat hij al die events waar aanroept zodra het form opnieuw gevuld worden, desnoods door het te forceren. Ik ben zelf al opzoek geweest hierna, maar kan niet vinden wat ik zoek. Het liefst zou ik gewoon alle controls doorlopend en daarvan hun gebruikte events aanroepen. Bij checkboxen dus CheckedChanged en bij de textboxen TextChanged etc.

Ik kom wel veel tegen over het gebruik van validate, maar vraag me af of dat de enige oplossing is, of dat ik iets anders over het hoofd zie. Plus dat ik dan ook alles weer moet gaan herschrijven.

Hopelijk kunnen jullie mij een eindje in de goede richting helpen.

Acties:
  • 0 Henk 'm!

  • Phyxion
  • Registratie: April 2004
  • Niet online

Phyxion

_/-\o_

Je kan zelf gewoon events invoken. Met de events die je nu hebt kan je alle events invoken voor het al dan niet enablen van een control. Ik denk dat als je op "Invoke" zoekt dat je wel aardig wat kan vinden.

'You like a gay cowboy and you look like a gay terrorist.' - James May


Acties:
  • 0 Henk 'm!

  • FireDrunk
  • Registratie: November 2002
  • Laatst online: 11:32
Om nou handmatig events te gaan raisen, vind ik niet zo'n nette oplossing...
Ik zou je architectuur eens bekijken, en kijken of je niet 1 functie kan maken waarin je al die componenten vult. Zodra je in het event van de listView je data ophaald, refresh je je data door die functie...
Zonder events... Ik zou (ookal zijn ze disabled) de data van elk veld toch invullen... Mocht de gebruiker ze dan enablen, zit de data er al gelijk in...

Even niets...


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Nu online
Vreemd dat die events niet getriggerd worden. Ik denk dat je beter eens je code debugged; het is een beetje moeilijk om er iets zinnigs over te zeggen op die manier.

Ik heb gelijkaardige dingen, maar bij mij werkt dit dan weer wel. :)
Offtopic, maar misschien wel handig voor jou: waarom maak je geen gebruik van databinding ? Dan hoef je zelf de code niet meer te schrijven om de controls op je form van de juiste waardes te gaan voorzien.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • Crazybyte
  • Registratie: Juli 2002
  • Laatst online: 02-09 15:23
thijs_cramer schreef op donderdag 16 juli 2009 @ 12:14:
Om nou handmatig events te gaan raisen, vind ik niet zo'n nette oplossing...
Ik zou je architectuur eens bekijken, en kijken of je niet 1 functie kan maken waarin je al die componenten vult. Zodra je in het event van de listView je data ophaald, refresh je je data door die functie...
Zonder events... Ik zou (ookal zijn ze disabled) de data van elk veld toch invullen... Mocht de gebruiker ze dan enablen, zit de data er al gelijk in...
Ik heb één functie waarmee ik alle componenten vul, die heet LoadFormWithValues(); en die maakt gebruik van een variabele initialValues, die reeds alle informatie bevat. Zodra je dus het event krijgt van de listView dan maakt hij eerst het form blanco met een functie LoadFormWithoutValues();, vervolgens laad ik de juiste data in initialValues en dan roep ik LoadFormWithValues(); weer aan om ze te vullen.

Het vullen gebeurt even goed, alleen bij het laden van het form (eerste keer) dan loopt ie automatisch door z'n events van de controls en daardoor worden alle juiste velden enabled.
whoami schreef op donderdag 16 juli 2009 @ 12:21:
Vreemd dat die events niet getriggerd worden. Ik denk dat je beter eens je code debugged; het is een beetje moeilijk om er iets zinnigs over te zeggen op die manier.
De code werkt gewoon, de events worden ook getriggered op het moment dat ik een checkbox check of uncheck. Zelfde voor textboxen als ik text verander.

Echter bij het laden van het form loopt ie er automatisch doorheen (de events), maar bij het opnieuw toewijzen van de gegevens niet.
whoami schreef op donderdag 16 juli 2009 @ 12:21:
Offtopic, maar misschien wel handig voor jou: waarom maak je geen gebruik van databinding ? Dan hoef je zelf de code niet meer te schrijven om de controls op je form van de juiste waardes te gaan voorzien.
Ik weet dat er zoiets is, maar ik moet dan nog helemaal gaan uitzoeken hoe hij op basis van een rij in de lijst, weet welke rij uit de tabel hij moet gebruiken en dan ook nog eens alle waarden op de juiste manier uitlezen naar de gebruikte velden.
Het zou wel ideaal zijn, maar weet niet of ik daar op dit moment de tijd voor heb om dat allemaal te gaan veranderen.
Phyxion schreef op donderdag 16 juli 2009 @ 12:08:
Je kan zelf gewoon events invoken. Met de events die je nu hebt kan je alle events invoken voor het al dan niet enablen van een control. Ik denk dat als je op "Invoke" zoekt dat je wel aardig wat kan vinden.
Ik zal er eens naar kijken, misschien niet het meest netst, maar wel afdoende voor nu.

Meer / betere / nettere oplossing zijn altijd welkom!

Acties:
  • 0 Henk 'm!

  • Mastermind
  • Registratie: Februari 2000
  • Laatst online: 01-09 22:18
Als een checkbox checked is en je zet hem op checked, verandert er niets dus raised hij geen event. In LoadFormWithoutValues(); moet je dus ook alle checkboxes CheckState=false zetten.

[ Voor 5% gewijzigd door Mastermind op 16-07-2009 13:40 ]


Acties:
  • 0 Henk 'm!

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 06-09 00:37

curry684

left part of the evil twins

Phyxion schreef op donderdag 16 juli 2009 @ 12:08:
Je kan zelf gewoon events invoken. Met de events die je nu hebt kan je alle events invoken voor het al dan niet enablen van een control. Ik denk dat als je op "Invoke" zoekt dat je wel aardig wat kan vinden.
Ik heb het gevoel dat je hier op de Control.Invoke method doelt en die is toch echt voor iets volstrekt anders bedoeld, namelijk een APC-wrapper voor multithreaded applications. Invoke heb je in 999 van de 1000 GUI-applicaties niet nodig.

Inhoudelijk voor TS: probeer GUI-interactie en functionaliteit zoveel mogelijk te scheiden. Ga dus niet in de CheckedChanged event de bewerkingen uitvoeren, maar roep in CheckedChanged een centrale functie aan:
C#:
1
2
3
4
5
6
private void SetCircuitBreakerState(bool newState)
{
  FACheckbox.Checked = newState;
  PartNumberTextBox.Enabled = newState;
  SpecificationTextBox.Enabled = newState;
}

Vervolgens kun je deze met false aanroepen vanuit ResetAllControls, welke je weer aanroept vanuit de constructor en eventuele andere plekken waar het nodig is.

[ Voor 33% gewijzigd door curry684 op 16-07-2009 13:53 ]

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • Phyxion
  • Registratie: April 2004
  • Niet online

Phyxion

_/-\o_

thijs_cramer schreef op donderdag 16 juli 2009 @ 12:14:
Om nou handmatig events te gaan raisen, vind ik niet zo'n nette oplossing...
Ik zou je architectuur eens bekijken, en kijken of je niet 1 functie kan maken waarin je al die componenten vult. Zodra je in het event van de listView je data ophaald, refresh je je data door die functie...
Zonder events... Ik zou (ookal zijn ze disabled) de data van elk veld toch invullen... Mocht de gebruiker ze dan enablen, zit de data er al gelijk in...
Het is inderdaad niet de meet nette oplossing maar voor TS waarschijnlijk voldoende.

@hierboven, nee.
Met multithreaded heb je inderdaad wel eens Invoke nodig met events om crossthread tegen te gaan.

[ Voor 15% gewijzigd door Phyxion op 16-07-2009 13:49 ]

'You like a gay cowboy and you look like a gay terrorist.' - James May


Acties:
  • 0 Henk 'm!

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 06-09 00:37

curry684

left part of the evil twins

Ga ze dan niet verwijzen naar Invoke want dan komen ze wel 99% zeker bij Control.Invoke uit ;)
Met multithreaded heb je inderdaad wel eens Invoke nodig met events om crossthread tegen te gaan.
Wtf is crossthread en waarom wil je het tegengaan.... je bedoelt het vast goed maar je omschrijvingen mogen hier en daar wat duidelijker 8)7

Invoke is een mechanisme om de inherente Win32-restrictie te omzeilen dat GUI-related acties alleen kunt uitvoeren in de thread context waarbinnen de handle origineel aangemaakt is. Dit gebeurt door middel van een asynchronous procedure call te queuen waardoor de code in kwestie binnen de correcte thread context wordt uitgevoerd. Met de property InvokeRequired kun je opvragen of de handle van een control aan de huidig actieve thread hangt.

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • Phyxion
  • Registratie: April 2004
  • Niet online

Phyxion

_/-\o_

curry684 schreef op donderdag 16 juli 2009 @ 13:57:
[...]

Ga ze dan niet verwijzen naar Invoke want dan komen ze wel 99% zeker bij Control.Invoke uit ;)

[...]

Wtf is crossthread en waarom wil je het tegengaan.... je bedoelt het vast goed maar je omschrijvingen mogen hier en daar wat duidelijker 8)7

Invoke is een mechanisme om de inherente Win32-restrictie te omzeilen dat GUI-related acties alleen kunt uitvoeren in de thread context waarbinnen de handle origineel aangemaakt is. Dit gebeurt door middel van een asynchronous procedure call te queuen waardoor de code in kwestie binnen de correcte thread context wordt uitgevoerd. Met de property InvokeRequired kun je opvragen of de handle van een control aan de huidig actieve thread hangt.
Ja, ben vandaag niet op mijn best met uitleggen en uitdrukken blijkbaar :> Kan maar beter stoppen voor vandaag :*)

Als je een CrossThreadException krijgt ben je bezig met een Control die gemaakt is op een andere thread.
Dan kan je inderdaad kijken of InvokeRequired is en dan kan je daar gebruik van maken met een 'echte' Invoke. Dat wat je hier zei is wat ik bedoelde, alleen heb jij het een stuk beter uitgelegd ;)

'You like a gay cowboy and you look like a gay terrorist.' - James May


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 11-09 12:01
Mastermind schreef op donderdag 16 juli 2009 @ 13:39:
Als een checkbox checked is en je zet hem op checked, verandert er niets dus raised hij geen event. In LoadFormWithoutValues(); moet je dus ook alle checkboxes CheckState=false zetten.
Wilde deze toch maar even quoten want het lijkt alsof er niet naar gekeken is.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • Crazybyte
  • Registratie: Juli 2002
  • Laatst online: 02-09 15:23
farlane schreef op donderdag 16 juli 2009 @ 14:30:
[...]
Wilde deze toch maar even quoten want het lijkt alsof er niet naar gekeken is.
Maar ik heb er wel naar gekeken ;)
Mastermind schreef op donderdag 16 juli 2009 @ 13:39:
Als een checkbox checked is en je zet hem op checked, verandert er niets dus raised hij geen event. In LoadFormWithoutValues(); moet je dus ook alle checkboxes CheckState=false zetten.
Blijkt inderdaad wel de oplossing te zijn, nu alleen nog even uitzoeken hoe dat bij de 2 radiobuttons gaat. Die hebben namelijk geen CheckState en daarbij gebeurt hetzelfde. Anders die dingen toch maar vervangen voor checkboxen.

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Nu online
Phyxion schreef op donderdag 16 juli 2009 @ 14:03:
[...]

Als je een CrossThreadException krijgt ben je bezig met een Control die gemaakt is op een andere thread.
Dan kan je inderdaad kijken of InvokeRequired is en dan kan je daar gebruik van maken met een 'echte' Invoke. Dat wat je hier zei is wat ik bedoelde, alleen heb jij het een stuk beter uitgelegd ;)
Ja, maar, dat heeft helemaal niets met dit probleem te maken ? Waar zie jij ergens dat de TS met MT aan de slag is ? Dat hij vanuit een andere thread een UI control wil gaan updaten ?
Maw: deze info is totaal irrelevant voor dit topic

https://fgheysels.github.io/

Pagina: 1