[c#] Custom event handlers. Hoe toepassen?

Pagina: 1
Acties:
  • 151 views sinds 30-01-2008
  • Reageer

  • mahi
  • Registratie: Juni 2001
  • Laatst online: 03-10-2025

mahi

God bless GoT

Topicstarter
Ik vind met Google niet echt veel duidelijke uitleg over custom event handlers, of user defined event handlers, dus ik weet niet zeker of datgene wat ik wil doen zo noemt. Ik zal daarom een simpel codevoorbeeldje geven en aan de hand daarvan duidelijk maken wat ik wil bekomen.

Ik heb een class "Form1" die een andere class "Form2" aanroept. Een van de event handlers van Form2 is bijvoorbeeld "Click" (Form2 is een form waarbij Click een voorgedefinieerde System.EventHandler is). Die Click event wordt in Form1 onderschept om er iets mee te doen. Enkel de relevante code is weergegeven:
C#:
1
2
3
4
5
6
7
8
public class Form2
{
    ...
    public Form2()
    {
        ...
    }
}
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Form1
{
    ...
    public Form1()
    {
        Form2 f2 = new Form2();
        // Click event handler van Form2
        f2.Click += new System.EventHandler(this.Form2Clicked);
        ...
    }

    // Wanneer de Click event van Form2 onderschept wordt,
    // wordt deze functie uitgevoerd.
    private Form2Clicked(object sender, System.EventArgs e)
    {
        MessageBox.Show("Geklikt op Form2");
    }
}
Het is duidelijk dat wanneer ik op Form2 klik, de event in Form1 onderschept zal worden en de messagebox zal verschijnen.

Allemaal goed en wel, maar eigenlijk zou ik graag een eigen - niet-voorgedefinieerde event aan Form2 willen hangen. Helaas vind ik nergens duidelijke uitleg hierover, waarschijnlijk omdat ik de verkeerde zoektermen gebruik. Ik heb al wel gevonden hoe ik zelf een event aanmaak, maar niet hoe ik deze trigger en in Form1 gebruik.
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public delegate void TestEvent();

public class Form2
{
    public event TestEvent Test;
    ...
    
    public Form2()
    {
        ...
    }
    
    private void Functie()
    {
        // Hier zou ik de Test event willen triggeren.
        ?????????
    }
}
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Form1
{
    ...
    public Form1()
    {
        Form2 f2 = new Form2();
        // Hier zou ik de Test event handler van Form2
        // willen koppelen aan Form2Test()
        f2.Test += ?????????
        ...
    }

    // Wanneer de Test event van Form2 onderschept wordt,
    // wordt deze functie uitgevoerd.
    private void Form2Test()
    {
        MessageBox.Show("Test van Form2");
    }
}
De vraagtekens duiden op de stukken die ik niet voor mekaar krijg. Dus kortweg weet ik niet hoe ik een event handler trigger. Nou ja, ik heb wel al met Invoke kunnen triggeren, maar dat lukt me enkel binnen dezelfde class omdat Invoke een target nodig heeft. Als dat target in dezelfde class ligt is dat geen probleem, maar nu bevindt het target (Form2Test) zich in de parent class (Form1). Form2 kan echter de variabelen en functies van Form1 niet zien (of ik moet met public static gaan werken en dat is absoluut niet de bedoeling).

De bedoeling is dus dat wanneer Functie() in Form2 uitgevoerd wordt (door god-weet-wat - is nu niet van belang), dat deze de Test event triggert vergelijkbaar met de Click event uit het eerste voorbeeld. Deze Test event moet dan in Form1 onderschept worden en gekoppeld worden aan de functie Form2Test().

Ik hoop dat ik het wat duidelijk heb kunnen omschrijven.

Wat ik wil is wel mogelijk denk ik. Immers, bij controls werkt het probleemloos zoals m'n eerste voorbeeld al aangaf. Maar daarbij gaat het om voorgedefinieerde events. Nu wil ik een eigen event gebruiken...

[ Voor 3% gewijzigd door mahi op 29-09-2005 14:39 ]

A bus station is where a bus stops. A train station is where a train stops... On my desk I have a workstation.


  • whoami
  • Registratie: December 2000
  • Laatst online: 17:18
Zoek eens op delegates, of kijk hier eens naar:
[rml]whoami in "[ VB.NET] waardes van een andere form?"[/rml]

Wat jij nog moet doen is:
code:
1
f2.Test = new TestEvent(Form2Test);


Hiermee koppel je de eventhandler (Form2Test) aan de event (Test).

Let wel, hiermee invoke je de eventhandler nog niet. Om de event-handler te 'invoken' moet je gaan zeggen aan de event dat hij z'n eventhandlers moet uitvoeren.

In jouw geval dus, ergens in form2:
code:
1
2
3
4
if( Test != null )
{
   Test();
}

[ Voor 42% gewijzigd door whoami op 29-09-2005 14:45 ]

https://fgheysels.github.io/


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
een simpel voorbeeldje is
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class EventTest
{
    public delegate void Test( int blaat );
    public event Test OnTest;

    public void SetTestHandler()
    {
        OnTest += new Test( MyTestHandler );
    }
    public void CallTestEvent()
    {
        if( OnTest != null )
            OnTest( 1 );
    }
    public void MyTestHandler( int blaat )
    {
        //DoSomething
    }
}

Jij hebt zowiezo geen Delegate gedefineerd. De delate is eigenlijk de method signature voor het event.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • whoami
  • Registratie: December 2000
  • Laatst online: 17:18
rwb schreef op donderdag 29 september 2005 @ 14:46:
Jij hebt zowiezo geen Delegate gedefineerd. De delate is eigenlijk de method signature voor het event.
Heeft ie wel hoor. :)
Kijk maar eens boven z'n definitie van Form2. ;)

https://fgheysels.github.io/


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Ok even overheen gelezen ;)

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Verwijderd

Volgens mij heb je aan een delegate genoeg (en dat is al de halve implementatie van een event).

Hier kan je wat meer info vinden over delegates: http://www.codeproject.com/useritems/Delegates_in_C_.asp

  • whoami
  • Registratie: December 2000
  • Laatst online: 17:18
Een event is eigenlijk een delegate, met dat verschil dat je er het 'event' keyword voorzet, wat er dan weer voor zorgt, dat je de delegate enkel (rechtstreeks) kunt 'invoken' in de class waar je de event gedefinieert hebt; that is, in de class waar de event een member van is.

https://fgheysels.github.io/


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
En dat je er meerdere EventHandlers aan kunt hangen. Bij een standaard delegate is het er standaard 1.

[edit]
mmm nou ik dit zo schrijf weet ik dat eigenlijk niet eens zeker. Even uitproberen.


[edit2]
Bij delegates kun je dus ook gewoon meer dan 1 handlers toevoegen d.m.v. += dacht eigenlijk altijd dat het 1 instantie was maar blijkbaar niet.

[ Voor 65% gewijzigd door Woy op 29-09-2005 15:03 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • whoami
  • Registratie: December 2000
  • Laatst online: 17:18
Dat kan een gewone delegate toch ook:

code:
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
public delegate void TestMulti();

    
public class DelegateTest
{
    
    public TestMulti        Bliep;
    
    public DelegateTest()
    {
            
    }
        
    public void ShowSubscr()
    {
        if( Bliep != null )
        {
            foreach( Delegate d in Bliep.GetInvocationList() )
            {
                Console.WriteLine ( d.Method.Name );
            }
        }
    }
        
    public void DoIt()
    {
        if( Bliep != null )
        {
            Bliep();
        }
    }
}


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
static void Main(string[] args)
{
            DelegateTest b = new DelegateTest();
            
            b.Bliep += new TestMulti(Test1);
            b.Bliep += new TestMulti(Test2);
            
            b.ShowSubscr();
            
            b.DoIt();

}
        
public static void Test1()
{
    Console.WriteLine ("t1");
}
        
public static void Test2()  
{
      Console.WriteLine ("t2");
}

https://fgheysels.github.io/


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
whoami schreef op donderdag 29 september 2005 @ 15:05:
Dat kan een gewone delegate toch ook:
yup. Ik vergiste me even. Komt denk omdat ik de laatste tijd vooral in gewoon c bezig bent en daar kan dat met function pointers natuurlijk niet

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • mahi
  • Registratie: Juni 2001
  • Laatst online: 03-10-2025

mahi

God bless GoT

Topicstarter
Inderdaad, bij delegates vind ik beduidend meer uitleg. Dat is het jammere aan zoeken... Als je niet weet hoe het noemt zul je niets vinden. Nou ja, het was wel vrij dom van me om niet aan het keyword delegate te denken. Maar ik was zo gefixeerd op event handlers omdat bij controls enkel over event handlers wordt gesproken.

Hoe dan ook, je codevoorbeeldje uit het andere topic was een ENORME hulp. Bedankt voor zulk een concreet voorbeeld. Je kunt niet geloven hoeveel meer een simpel maar uitgewerkt voorbeeld iets duidelijk maakt, dan een hoop theorie :)

Ik heb mijn code aangepast naar analogie van je voorbeeld en nu werkt het als een trein. Hoewel vast maar een klein onderdeel van delegates en events begrijp ik de werking ervan nu heel wat beter.

Ik ga nu nog wat meer lezen over het verschil tussen events en delegates zodat ik weet wanneer welke optimaal gebruiken.

Natuurlijk ook bedankt aan de anderen in de thread!

A bus station is where a bus stops. A train station is where a train stops... On my desk I have a workstation.


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

rwb schreef op donderdag 29 september 2005 @ 14:55:
Bij delegates kun je dus ook gewoon meer dan 1 handlers toevoegen d.m.v. += dacht eigenlijk altijd dat het 1 instantie was maar blijkbaar niet.
idd, en dat is denk ik ook de reden waarom je niet moet controleren of je "event == null" ?

ASSUME makes an ASS out of U and ME


  • whoami
  • Registratie: December 2000
  • Laatst online: 17:18
Daarmee check je gewoon of er wel een eventhandler is voor jouw event.

https://fgheysels.github.io/


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12:01

curry684

left part of the evil twins

rwb schreef op donderdag 29 september 2005 @ 14:55:
Bij delegates kun je dus ook gewoon meer dan 1 handlers toevoegen d.m.v. += dacht eigenlijk altijd dat het 1 instantie was maar blijkbaar niet.
Standaard delegate is juist van het type System.MulticastDelegate, voor een System.Delegate moet je juist handmatig aan de gang :)

Professionele website nodig?


Verwijderd

Ik heb ook een probleem met event handlers.. heb het gedaan zoals hier, en heb dan deze code:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
namespace Server
{
    //Public delegates  
    public delegate void ConnectDelegate(object sender, EventArgs e);
    
//Client class
    public class Client
    {

        //Events Defination
        public event ConnectDelegate Connected;
        
        //Hoop andere code
        if (Connected != null)
        {
                EventArgs e = new EventArgs();
                Connected(this, e);
        }
     }
}


En in een andere form heb ik dan:
code:
1
2
3
4
5
6
7
Client newClient = new Client(tcpListener.AcceptSocket());
newClient.Connected += new ConnectDelegate(this.OnConnected);

public void OnConnected(object sender, EventArgs e)
{
//Code
}


Maar die connected() is ALTIJD NULL.. hoe kan dat nou ? Ik snap er werkelijk nix van.. als ik die If er niet bij zet, loopt ie keihard vast, krak.. niks meer :S

  • whoami
  • Registratie: December 2000
  • Laatst online: 17:18
ben je wel zeker dat je die code uitvoert ?
(Ik bedoel, deze code:
code:
1
newClient.Connected += new ...

?

Heb je wel al eens een breakpoint gezet in je code, en gekeken dmv de debugger of die code daadwerkelijk uitgevoerd wordt ?

https://fgheysels.github.io/


  • pjonk
  • Registratie: November 2000
  • Laatst online: 29-12-2025
Ik zie niet zo gauw een fout in je code, debuggen dus zoals whoami aandraagt. Ik zou wel de naamgeving van je delegate aanpassen naar de door Microsoft aanbevolen guidelines, dus:
code:
1
2
3
    //Public delegates  
    public delegate void ConnectedEventHandler(object sender, EventArgs e);
    public event ConnectedEventHandler Connected;


Kijk bijv. naar de code voorbeelden op de microsoft site:
http://msdn.microsoft.com...l/vcwlkeventstutorial.asp

[ Voor 23% gewijzigd door pjonk op 27-12-2005 12:34 ]

It’s nice to be important but it’s more important to be nice


Verwijderd

whoami schreef op maandag 26 december 2005 @ 22:05:
ben je wel zeker dat je die code uitvoert ?
(Ik bedoel, deze code:
code:
1
newClient.Connected += new ...

?

Heb je wel al eens een breakpoint gezet in je code, en gekeken dmv de debugger of die code daadwerkelijk uitgevoerd wordt ?
Yep, die code wordt uitgevoerd.. Ik heb ook gekeken naar het voorbeeld op de site en ik doe naar mijn weten precies hetzelfde... Ik snap echt niet waarom hij het niet doet, ik heb netjes buiten de class die delegate, daarna in de class zelf het Event. En dan in een form maak ik de class met new aan, en koppel er een functie in de form aan doormiddel van class.connected += new blabla...

Ik heb breakpoints en dergelijke erin gezet.. en alles wordt uitgevoerd naar mijn weten.. zal het nog eens gaan checken...

EDIT:

Ik weet denk ik al wat er aan de hand is.. De code wordt al uitgevoerd voordat ik de event er aanvast koppel, had namelijk dingen in de constructor gezet...

Updateje: Ja... dat was het.. thanks :)

[ Voor 12% gewijzigd door Verwijderd op 27-12-2005 11:51 ]

Pagina: 1