none
Trigger - Event or delegate with event RRS feed

  • Question

  • Hello,
    I want to trigger an action on a trigger, similar to button click.
    I have the possibility of an event and a combination of event and delegate.
    When do you take something the best?
    I see no difference, no sense. It's best to just take the event handler?
    Maybe someone knows an understandable simple explanation. Perhaps also an example.
    But I hope someone can easy explain it.
    With best regards Markus
    public delegate void EventHandlerContentSentBack(Object sender, string e);
    public event EventHandlerContentSentBack EvHaContentSentBack;
    public event EventHandler ThresholdReached;
    
    private void RS232_EvHaContentSentBack(object sender, string e)
    {
       // e += Environment.NewLine;
     Dispatcher.Invoke((Action)(() => txtSentBack.Text += e));
     Dispatcher.Invoke((Action)(() => txtSentBack.Focus()));
     Dispatcher.Invoke((Action)(() => txtSentBack.CaretIndex = txtSentBack.Text.Length));
     Dispatcher.Invoke((Action)(() => txtSentBack.ScrollToEnd()));
    }
    private void RS232_ThresholdReached(object sender, EventArgs e)
    {
     throw new NotImplementedException();
    }
    With best regards Markus


    Thursday, January 17, 2019 5:38 PM

All replies

  • If you need to notify users external to the type about something then use an event. Note that delegates and events are not exclusive things. In fact delegates are how events work. Delegate is a function object (functor in other languages) and is what you use to hook up event handlers.

    I suspect you are thinking of a callback (which also uses delegates) which is different. A callback is used when code needs to call a function in order to work. There are a couple things that I think are important when deciding callback vs event - # of listeners and responsibility. Events can have any # of listeners, including 0. Callbacks can have 1 (or 0 if it is optional).

    •  Events (notification model)
    •      More than 1 listener is possible
    •      Having no listeners doesn't change the calling code in any way 
    •  Callbacks (interaction model)
    •      0 or 1 listener
    •      Having no listener is either not supported or explicitly coded around
    •      Listener plays an integral part in the calling code (e.g. making decisions)

    As an example, changing the currently selected object in a drawing program may require a "properties" window to be updated, the UI to refresh and perhaps the status bar to change. Since the code doesn't know who wants to be notified and what they'll do an event is appropriate.

    class SelectionManager
    {
       public DrawObject Selected { get; }
       
       public event EventHandler SelectionChanged;
    }
    
    class PropertyWindow
    {
       void Initialize ( SelectionManager manager )
       {
          manager.SelectionChanged += UpdateUI;
       }
    
       void UpdateUI ( object sender, EventArgs e )
       {      
       }
    }
    
    class StatusBar
    {
       void Initialize ( SelectionManager manager )
       {
          manager.SelectionChanged += UpdateUI;
       }
    
       void UpdateUI ( object sender, EventArgs e )
       {      
       }
    }

    But if you want to implement a visitor pattern where you enumerate the windows on the desktop then a callback is more appropriate. It is a one time thing (during the course of the enumeration) and only the calling code will care.

    public delegate bool EnumWindowsDelegate ( IntPtr window );
    
    class WindowEnumerator
    {   
       public void EnumerateWindows ( EnumWindowsDelegate callback )
       {
          //Get next window
          var window = …;
    
          //Notify callback
          callback(window);
       }
    }

    In your sample code EventHandlerContentSentBack looks like a callback. Events always have a second parameter of EventArgs (or a type derived from it). So it is inappropriate to define that delegate and then expose it as an event. Do one or the other. I think an event is appropriate here because the handler is reacting to the event, not an integral part of it. Others may be interested as well. It is a notification that something occurred.

    class ContentSentBackEventArgs : EventArgs
    {
       public ContentSentBackEventArgs ( string value )
       {
          Content = value;
       }
    
       public string Content { get; private set; }
    }
    
    class RS232
    {
       public event EventHandler<ContentSentBackEventArgs> EvHaContentSentBack;
    
       public event EventHandler ThresholdReached;
    }
    
    //Consumer
    class MyClass
    {   
       public void Initialize ( RS232 rs232 )
       {
          rs232.EvHaContentSentBack += OnContentSentBack;
       }
    
       private void OnContentSentBack ( object sender, ContentSentBackEventArgs e )
       {
          Dispatcher.Invoke((Action)(() => {
             txtSentBack.Text += e.Content;
             txtSentBack.Focus();
             ...
          });
       }
    }


    Michael Taylor http://www.michaeltaylorp3.net

    Friday, January 18, 2019 3:45 PM
    Moderator