Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[C#] FormClosingEvent stopt ongewenst

Pagina: 1
Acties:

  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 17-10 16:43
Omdat ik niet wil dat als iemand op het kruisje drukt van een scherm een scherm zomaar sluit zonder (evt.) op te slaan en nog een laatste regeltje code uit te voeren heb ik het volgende gedaan.

Het form een nieuwe eventhandler gegeven voor FormCloseing (Occurs before the form is closed.)

Natuurlijk kom je in een oneindige loop als je in FormCloseing telkens vraagt ja, nee annuleren
Dus experimenteerde ik met een andere methode die ja/nee/annuleren koos en dan

this.close()

uitvoerde. de FormCloseing had dan een check of de CloseReason ApplicationExitCall of UserExitCall was. Helaas werkte dit niet omdat this.close() ook een UserExitCall genereerd. (vreemd zie ook: http://forums.microsoft.c...px?PostID=502448&SiteID=1 )

Maargoed, toen heb ik ipv this.close() maar expliciet het volgende gedaan:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private void btnClose_Click(object sender, EventArgs e)
        {
            //vragen wat er moet gebeuren en daarna sluiten
            CloseForm(this, new FormClosingEventArgs(CloseReason.ApplicationExitCall, false));
        }
private void CloseForm(object sender, FormClosingEventArgs e) 
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                e.Cancel = true;
                btnClose_Click(new Object(), new EventArgs());
            }
            else
            {
                e.Cancel = false;
                GlobalManager.removeListner(this);                
            }
        }       


e.Cancel = true zou het volgende moeten doen volgens intellisense
"get or set the value indicating that the event should be cancelled"

Dat interpreteer ik als, stel e.Cancel = true in om niet te het scherm te sluiten, maar e.Cancel = false om het scherm wel te sluiten.

Maar helaas gaat het event niet door met het scherm sluiten,

Dit lijkt me de meest logisch manier om op te berijken wat ik, maar helaas werkt het dus somehow niet zoals ik geplanned had :/ op google kan ik niets vinden behalve dingen als dit:
http://bytes.com/forum/thread589284.html

Die juist bevestigen dat het zou moeten werken zoals ik denk.

(Ik heb ook nog naar de MDI pagina gekeken helaas is die deze keer niet al te duidelijk: http://msdn2.microsoft.co...rms.form.formclosing.aspx )


Dus tsja, hoe sluit ik het scherm "soms" dmv van een event handler?

Edit: ik weet dat ik niet expliciet nogmaals cancel = false hoef te doen, maar dan is het wat duidelijker, en ook als ik dat stukje code weghaal helpt het niets, btw de false als 2e argument voor
CloseForm(this, new FormClosingEventArgs(CloseReason.ApplicationExitCall, false)); stelt ook al cancel op false in.

[ Voor 6% gewijzigd door roy-t op 09-04-2008 23:02 ]

~ Mijn prog blog!


  • pedorus
  • Registratie: Januari 2008
  • Niet online
Je roept zelf een eventhandler aan en dan ben je verbaasd dat de code die die eventhandler normaal gesproken aanriep niet wordt uitgevoerd?
Form.close raised normaal gesproken Form.Closing. Als je Form.Closing zelf gaat aanroepen, dan worden de normale acties van Form.Close natuurlijk niet opeens gedaan.
Mogelijke oplossing: zet bij de button een variabele die je checked bij Closing.

Maar waarom moet je niet gewoon een vraag krijgen als je op het kruisje klikt? Ik zou gewoon de vraag in Closing doen en de button alleen Close laten aanroepen.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 17-10 16:43
pedorus schreef op donderdag 10 april 2008 @ 00:21:
Je roept zelf een eventhandler aan en dan ben je verbaasd dat de code die die eventhandler normaal gesproken aanriep niet wordt uitgevoerd?
Form.close raised normaal gesproken Form.Closing. Als je Form.Closing zelf gaat aanroepen, dan worden de normale acties van Form.Close natuurlijk niet opeens gedaan.
Mogelijke oplossing: zet bij de button een variabele die je checked bij Closing.

Maar waarom moet je niet gewoon een vraag krijgen als je op het kruisje klikt? Ik zou gewoon de vraag in Closing doen en de button alleen Close laten aanroepen.
Sorry maar wat je zegt klopt volgens google en de documentatie niet:
http://forums.microsoft.c...px?PostID=620208&SiteID=1

Unfortunately, the CloseReason enum doesn't distinguish between the user closing the form and your code closing the form. A bit of oversight I'd say but there is probably a Windows restriction that forces that. The workaround is pretty straight-forward:

private bool mItsMeClosingIt;
...
public sub CloseForm() {
mItsMeClosingIt = true;
this.Close();
}
...
if (e.CloseReason == CloseReason.UserClosing) e.Cancel = !mItsMeClosingIt;
Een dev op microsoft.com gaf de volgende oplossing aan een gebruiker, en zoals je ziet wordt voor het closen alleen Cancel op true of false gezet, ik heb het idee dat FormClosing een event als ref mee krijgt en die veranderd, en door de stack na het FormClosing Event automatisch het FormClosed event komt, dat het form sluit aan de hand van dezelfde EventArgs, of iig EventArgs met daarin in ref met dezelfde e.Cancel

Dit is iig het beeld dat ik krijg van google zoek opdrachten.

En wat als anwser op microsoft.com staat aan gemerkt, maargoed, de code werkt niet die ik heb geschreven.

Doh:
Ik denk nu dat dat komt omdat ik geen nieuw event raise maar gewoon de method call, dat ga ik dus is even proberen!



Na wat verdere google searches blijkt dat ik niet manueel een FormClosingEvent kan raisen, ik heb het dus maar opgelost op dezelfde manier als hierboven beschreven door middel van een boolean, maar dat lijkt me toch niet de meeste mooie/elegante manier en het lijkt me gewoon dat dit mooier moet kunnen, vooral de keuze van MS om this.close() als CloseReason user mee te geven is toch wel erg wrang jammer dat this.close niet een contructor heeft waarin je de closereason kan mee geven, want in dat geval zou ik er met deze code al komen:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
//wishfullthinking, werkt dus niet!
private void CloseForm(object sender, FormClosingEventArgs e) 
        {            
            if (e.CloseReason == CloseReason.UserClosing)
            {                
                    e.Cancel = true;
                    btnClose_Click(this, new EventArgs());             
            }
            else
            {                
                GlobalManager.removeListner(this);                
            }
        }       

[ Voor 20% gewijzigd door roy-t op 10-04-2008 09:19 ]

~ Mijn prog blog!


  • pedorus
  • Registratie: Januari 2008
  • Niet online
Volgens mij geeft die dev precies mijn oplossing eigenlijk (variabele/boolean gebruiken).
Maar goed, na nog eens kijken naar de code, lijkt het erop alsof je toch gewoon het volgende wil:

In btnClose_Click slechts:
C#:
1
Close();

In CloseForm (event Form.Closing; pseudocode):
C#:
1
2
3
4
5
6
7
if (e.CloseReason == CloseReason.UserClosing) {
    vraagAntwoord=...;
    if (vraagAntwoord==Yes)
        Save()
    else if (vraagAntwoord==Annuleren)
        e.Cancel=true;
}

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Jij moet het formulier zelf sluiten middels Form.Close(). Form.Close roept dan het Form.Closing event aan en als je dan e.Cancel op true zet, dan wordt het form(ulier) niet gesloten.

MSDN bij beschrijving System.Windows.Form.Close (sectie Remarks):
When a form is closed, all resources created within the object are closed and the form is disposed. You can prevent the closing of a form at run time by handling the Closing event and setting the Cancel property of the CancelEventArgs passed as a parameter to your event handler. If the form you are closing is the startup form of your application, your application ends.
Alle sluit methodes worden automatisch naar Form.Close doorgeleid en daarom maakt het niet uit of jij Close aanroept of dat de gebruiker op een kruisje clicked. Wat jij nu eerst even moet doen is het closing event afvangen in je code en daarna echt de MSDN gaan doorlezen, want deze problemen die jij nu tegenkomt staan daar echt allemaal in beschreven.

If it isn't broken, fix it until it is..


  • DrDelete
  • Registratie: Oktober 2000
  • Laatst online: 13:07
roy-t schreef op woensdag 09 april 2008 @ 23:01:
Omdat ik niet wil dat als iemand op het kruisje drukt van een scherm een scherm zomaar sluit zonder (evt.) op te slaan en nog een laatste regeltje code uit te voeren heb ik het volgende gedaan.

...... knip
Waarom niet gewoon het FormClosing event implementeren?

code:
1
2
3
4
private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
  e.Cancel = true;
}

  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 17-10 16:43
DrDelete schreef op donderdag 10 april 2008 @ 10:26:
[...]


Waarom niet gewoon het FormClosing event implementeren?

code:
1
2
3
4
private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
  e.Cancel = true;
}
;) dat lijkt leuke code, maar op die manier is het scherm natuurlijk nooit meer te sluiten, ik heb trouwens dat event geimplementeerd, dus ik je post niet helemaal :)

Verder kan ik inderdaad de buttonclose functie beter in het event zetten, dat zal ik even fixen, nogmaals bedankt iedereen.

~ Mijn prog blog!


  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Je kunt natuurlijk op dat punt natuurlijk ook MessageBox.Show aanroepen met een yes/no/cancel button layout. Bij een keuze voor cancel, maar je e.cancel = true. Bij de keuze ja, sla je de gegevens op en bij nee doe je verder niets.

We hoeven toch niet alles te gaan voorkauwen? Een beetje hersen activiteit misstaat niet bij een programmeur.

If it isn't broken, fix it until it is..

Pagina: 1