visual - tipos de eventos c#




Noções básicas sobre eventos e manipuladores de eventos em c# (8)

Apenas para adicionar as grandes respostas existentes aqui - construindo o código no código aceito, que usa um delegate void MyEventHandler(string foo) ...

Porque o compilador conhece o tipo de delegado do evento SomethingHappened , isso:

myObj.SomethingHappened += HandleSomethingHappened;

É totalmente equivalente a:

myObj.SomethingHappened += new MyEventHandler(HandleSomethingHappened);

E os manipuladores também podem ser cancelados com -= assim:

// -= removes the handler from the event's list of "listeners":
myObj.SomethingHappened -= HandleSomethingHappened;

Por uma questão de integridade, aumentar o evento pode ser feito assim, somente na classe que possui o evento:

//Firing the event is done by simply providing the arguments to the event:
var handler = SomethingHappened; // thread-local copy of the event
if (handler != null) // the event is null if there are no listeners!
{
    handler("Hi there!");
}

A cópia de thread local do manipulador é necessária para garantir que a invocação seja thread-safe - caso contrário, um thread poderia ir e cancelar o registro do último manipulador para o evento imediatamente depois de verificarmos se era null , e teríamos uma "diversão" NullReferenceException lá.

C # 6 introduziu um bom ponteiro curto para esse padrão. Ele usa o operador de propagação nulo.

SomethingHappened?.Invoke("Hi there!");

Eu entendo o propósito dos eventos, especialmente dentro do contexto de criação de interfaces de usuário. Eu acho que esse é o protótipo para criar um evento:

public void EventName(object sender, EventArgs e);

O que os manipuladores de eventos fazem, por que são necessários e como criar um?


Aqui está um exemplo de código que pode ajudar:

using System;
using System.Collections.Generic;
using System.Text;

namespace Event_Example
{
  // First we have to define a delegate that acts as a signature for the
  // function that is ultimately called when the event is triggered.
  // You will notice that the second parameter is of MyEventArgs type.
  // This object will contain information about the triggered event.

  public delegate void MyEventHandler(object source, MyEventArgs e);

  // This is a class which describes the event to the class that receives it.
  // An EventArgs class must always derive from System.EventArgs.

  public class MyEventArgs : EventArgs
  {
    private string EventInfo;

    public MyEventArgs(string Text) {
      EventInfo = Text;
    }

    public string GetInfo() {
      return EventInfo;
    }
  }

  // This next class is the one which contains an event and triggers it
  // once an action is performed. For example, lets trigger this event
  // once a variable is incremented over a particular value. Notice the
  // event uses the MyEventHandler delegate to create a signature
  // for the called function.

  public class MyClass
  {
    public event MyEventHandler OnMaximum;

    private int i;
    private int Maximum = 10;

    public int MyValue
    {
      get { return i; }
      set
      {
        if(value <= Maximum) {
          i = value;
        }
        else 
        {
          // To make sure we only trigger the event if a handler is present
          // we check the event to make sure it's not null.
          if(OnMaximum != null) {
            OnMaximum(this, new MyEventArgs("You've entered " +
              value.ToString() +
              ", but the maximum is " +
              Maximum.ToString()));
          }
        }
      }
    }
  }

  class Program
  {
    // This is the actual method that will be assigned to the event handler
    // within the above class. This is where we perform an action once the
    // event has been triggered.

    static void MaximumReached(object source, MyEventArgs e) {
      Console.WriteLine(e.GetInfo());
    }

    static void Main(string[] args) {
      // Now lets test the event contained in the above class.
      MyClass MyObject = new MyClass();
      MyObject.OnMaximum += new MyEventHandler(MaximumReached);
      for(int x = 0; x <= 15; x++) {
        MyObject.MyValue = x;
      }
      Console.ReadLine();
    }
  }
}

Essa é, na verdade, a declaração para um manipulador de eventos - um método que será chamado quando um evento for disparado. Para criar um evento, você escreveria algo assim:

public class Foo
{
    public event EventHandler MyEvent;
}

E então você pode se inscrever no evento assim:

Foo foo = new Foo();
foo.MyEvent += new EventHandler(this.OnMyEvent);

Com OnMyEvent () definido assim:

private void OnMyEvent(object sender, EventArgs e)
{
    MessageBox.Show("MyEvent fired!");
}

Sempre que Foo disparar MyEvent , seu manipulador OnMyEvent será chamado.

Você nem sempre precisa usar uma instância de EventArgs como o segundo parâmetro. Se você quiser incluir informações adicionais, poderá usar uma classe derivada de EventArgs ( EventArgs é a base por convenção). Por exemplo, se você observar alguns dos eventos definidos em Control no WinForms ou FrameworkElement no WPF, poderá ver exemplos de eventos que transmitem informações adicionais aos manipuladores de eventos.


Eu concordo com o KE50, exceto que eu vejo a palavra-chave 'event' como um apelido para 'ActionCollection', pois o evento contém uma coleção de ações a serem executadas (isto é, o delegado).

using System;

namespace test{

class MyTestApp{
    //The Event Handler declaration
    public delegate void EventAction();

    //The Event Action Collection 
    //Equivalent to 
    //  public List<EventAction> EventActions=new List<EventAction>();
    //        
    public event EventAction EventActions;

    //An Action
    public void Hello(){
        Console.WriteLine("Hello World of events!");
    }
    //Another Action
    public void Goodbye(){
        Console.WriteLine("Goodbye Cruel World of events!");
    }

    public static void Main(){
        MyTestApp TestApp = new MyTestApp();

        //Add actions to the collection
        TestApp.EventActions += TestApp.Hello;
        TestApp.EventActions += TestApp.Goodbye;

        //Invoke all event actions
        if (TestApp.EventActions!= null){
            //this peculiar syntax hides the invoke 
            TestApp.EventActions();
            //using the 'ActionCollection' idea:
            // foreach(EventAction action in TestApp.EventActions)
            //     action.Invoke();
        }
    }

}   

}

Grandes respostas técnicas no post! Não tenho nada tecnicamente para adicionar a isso.

Uma das principais razões pelas quais os novos recursos aparecem em linguagens e softwares em geral é marketing ou política da empresa! :-) Isso não deve ser subestimado!

Eu acho que isso se aplica a certa extensão para delegados e eventos também! Eu os acho úteis e adiciono valor à linguagem C #, mas por outro lado a linguagem Java decidiu não usá-los! eles decidiram que o que quer que você esteja resolvendo com os delegados, você já pode resolver com os recursos existentes da linguagem, isto é, interfaces, por exemplo.

Agora, por volta de 2001, a Microsoft lançou o .NET framework e a linguagem C # como uma solução concorrente para Java, então foi bom ter NOVOS RECURSOS que o Java não possui.


Minha compreensão dos eventos é;

Delegar:

Uma variável para manter referência ao método / métodos a serem executados. Isso torna possível passar métodos como uma variável.

Etapas para criar e chamar o evento:

  1. O evento é uma instância de um delegado

  2. Como um evento é uma instância de um delegado, precisamos primeiro definir o delegado.

  3. Atribuir o método / métodos a serem executados quando o evento for disparado ( Chamando o delegado )

  4. Incêndio do evento ( ligue para o delegado )

Exemplo:

using System;

namespace test{
    class MyTestApp{
        //The Event Handler declaration
        public delegate void EventHandler();

        //The Event declaration
        public event EventHandler MyHandler;

        //The method to call
        public void Hello(){
            Console.WriteLine("Hello World of events!");
        }

        public static void Main(){
            MyTestApp TestApp = new MyTestApp();

            //Assign the method to be called when the event is fired
            TestApp.MyHandler = new EventHandler(TestApp.Hello);

            //Firing the event
            if (TestApp.MyHandler != null){
                TestApp.MyHandler();
            }
        }

    }   

}

editora: onde os eventos acontecem. O Publisher deve especificar qual delegado a classe está usando e gerar os argumentos necessários, passar esses argumentos e a si mesmo para o delegado.

assinante: onde a resposta acontece. O assinante deve especificar métodos para responder aos eventos. Esses métodos devem ter o mesmo tipo de argumentos que o delegado. O Assinante adiciona esse método ao representante do editor.

Portanto, quando o evento acontecer no editor, o delegado receberá alguns argumentos do evento (dados, etc), mas o editor não tem idéia do que acontecerá com todos esses dados. Os inscritos podem criar métodos em sua própria turma para responder a eventos na turma do editor, para que os inscritos possam responder aos eventos do editor.


//This delegate can be used to point to methods
//which return void and take a string.
public delegate void MyDelegate(string foo);

//This event can cause any method which conforms
//to MyEventHandler to be called.
public event MyDelegate MyEvent;

//Here is some code I want to be executed
//when SomethingHappened fires.
void MyEventHandler(string foo)
{
    //Do some stuff
}

//I am creating a delegate (pointer) to HandleSomethingHappened
//and adding it to SomethingHappened's list of "Event Handlers".
myObj.MyEvent += new MyDelegate (MyEventHandler);






event-handling