EventHandlerList question (1.1)

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • DeveloperX

    EventHandlerList question (1.1)

    I'm having a play with EventHandlerLis t but the documentation is a bit
    ropey and I can't find any decent examples. It also doesn't seem to do
    what I was led to believe it would. I was under the impression that
    windows.forms controls used EventHandlerLis ts because generally most
    events aren't consumed so this saves memory.
    I can add a button to a form, and have

    this.button9.Cl ick += new System.EventHan dler(this.butto n9_Click);
    this.button9.Cl ick += new System.EventHan dler(this.butto n9b_Click);

    which will successfully fire off both functions when the button is
    clicked.

    The EventHandlerLis t does not fire both as it keys the delegate in a
    hashtable and overwrites the first reference with the second reference
    (This is using AddHandler).
    More confusingly in trying to get the thing running I see code all over
    the internet that can't run. A VB example that used a foreach (there's
    no enumerator so that can't work) and a C++ example where the
    EventHandlerLis t returns an EventHandler (It only returns Delegates in
    my tests)
    I'm certain I'm right, I can see plenty of alternative ways of doing it
    that would work, I'm just confused about the information I'm getting
    off the internet.
    So am I being fed porkies? Do Windows Forms controls use
    EventHandlerLis t objects and if so how come their implementation allows
    for += and the one in ComponentModel doesn't?

    Thanks
    Ian

  • Dave Sexton

    #2
    Re: EventHandlerLis t question (1.1)

    Hi Ian,

    <snip>
    I was under the impression that
    windows.forms controls used EventHandlerLis ts because generally most
    events aren't consumed so this saves memory.
    True.
    I can add a button to a form, and have
    >
    this.button9.Cl ick += new System.EventHan dler(this.butto n9_Click);
    this.button9.Cl ick += new System.EventHan dler(this.butto n9b_Click);
    >
    which will successfully fire off both functions when the button is
    clicked.
    >
    The EventHandlerLis t does not fire both as it keys the delegate in a
    hashtable and overwrites the first reference with the second reference
    (This is using AddHandler).
    Here's an example that I'm using from a project I'm working on right now in a
    class that derives from Component:

    private readonly object ServiceViewChan gedEvent = new object();

    public event EventHandler<Se rviceViewChange dEventArgsServi ceViewChanged
    {
    add
    {
    lock (ServiceViewCha ngedEvent)
    {
    Events.AddHandl er(ServiceViewC hangedEvent, value);
    }
    }
    remove
    {
    lock (ServiceViewCha ngedEvent)
    {
    Events.RemoveHa ndler(ServiceVi ewChangedEvent, value);
    }
    }
    }

    private void OnServiceViewCh anged(ServiceVi ewChangedEventA rgs e)
    {
    EventHandler<Se rviceViewChange dEventArgshandl er = null;

    lock (ServiceViewCha ngedEvent)
    {
    handler = (EventHandler<S erviceViewChang edEventArgs>)
    Events[ServiceViewChan gedEvent];
    }

    if (handler != null)
    handler(this, e);
    }
    More confusingly in trying to get the thing running I see code all over
    the internet that can't run. A VB example that used a foreach (there's
    no enumerator so that can't work) and a C++ example where the
    EventHandlerLis t returns an EventHandler (It only returns Delegates in
    my tests)
    EventHandler is a delegate. The value returned by the EventHandlerLis t
    indexer isn't type-safe, so it must be cast into the appropriate delegate
    Type, as you can see in the code above.
    I'm certain I'm right, I can see plenty of alternative ways of doing it
    that would work, I'm just confused about the information I'm getting
    off the internet.
    So am I being fed porkies? Do Windows Forms controls use
    EventHandlerLis t objects and if so how come their implementation allows
    for += and the one in ComponentModel doesn't?
    An EventHandlerLis t instance is exposed as a protected property named,
    "Events" from the Component class to all derived types. The "+=" operator
    acts on public events, not the "Events" property. The underlying
    implementation of "add" and "remove" on these public events can use the
    "Events" property, internally, to store the supplied delegate.

    Yes, I'm sure WinForms controls use the Events property, though I'm not sure
    if ALL events on ALL WinForms Controls are registered through the inherited
    Component.Event s property. Web controls use the "Events" property as well,
    but it's declared in the base Control since Control doesn't derive from
    Component. It still works the same way.

    In my example, the public event is "ServiceViewCha nged". The "add" and
    "remove" implementations of that event, which correspond to the "+=" and "-="
    operators, respectively, add or remove the supplied delegate to or from the
    underlying EventHandlerLis t by calling either Events.AddHandl er or
    Events.RemoveHa ndler. Both of these methods require the same key used in the
    indexer when you attempt to retrieve the delegate reference from the list.

    If things still aren't clear, let me know.

    --
    Dave Sexton


    Comment

    • Dave Sexton

      #3
      Re: EventHandlerLis t question (1.1)

      Hi Ian,

      Sorry about using C# generics - I just realized you wrote (1.1) in the title.

      To be honest, I don't have a code snippet without generics on hand anyway. If
      you need me to rewrite my example without generics I will - just let me know.

      --
      Dave Sexton

      "Dave Sexton" <dave@jwa[remove.this]online.comwrote in message
      news:%23xyoZP4A HHA.3380@TK2MSF TNGP04.phx.gbl. ..
      Hi Ian,
      >
      <snip>
      >
      >I was under the impression that
      >windows.form s controls used EventHandlerLis ts because generally most
      >events aren't consumed so this saves memory.
      >
      True.
      >
      >I can add a button to a form, and have
      >>
      >this.button9.C lick += new System.EventHan dler(this.butto n9_Click);
      >this.button9.C lick += new System.EventHan dler(this.butto n9b_Click);
      >>
      >which will successfully fire off both functions when the button is
      >clicked.
      >>
      >The EventHandlerLis t does not fire both as it keys the delegate in a
      >hashtable and overwrites the first reference with the second reference
      >(This is using AddHandler).
      >
      Here's an example that I'm using from a project I'm working on right now in
      a class that derives from Component:
      >
      private readonly object ServiceViewChan gedEvent = new object();
      >
      public event EventHandler<Se rviceViewChange dEventArgsServi ceViewChanged
      {
      add
      {
      lock (ServiceViewCha ngedEvent)
      {
      Events.AddHandl er(ServiceViewC hangedEvent, value);
      }
      }
      remove
      {
      lock (ServiceViewCha ngedEvent)
      {
      Events.RemoveHa ndler(ServiceVi ewChangedEvent, value);
      }
      }
      }
      >
      private void OnServiceViewCh anged(ServiceVi ewChangedEventA rgs e)
      {
      EventHandler<Se rviceViewChange dEventArgshandl er = null;
      >
      lock (ServiceViewCha ngedEvent)
      {
      handler = (EventHandler<S erviceViewChang edEventArgs>)
      Events[ServiceViewChan gedEvent];
      }
      >
      if (handler != null)
      handler(this, e);
      }
      >
      >More confusingly in trying to get the thing running I see code all over
      >the internet that can't run. A VB example that used a foreach (there's
      >no enumerator so that can't work) and a C++ example where the
      >EventHandlerLi st returns an EventHandler (It only returns Delegates in
      >my tests)
      >
      EventHandler is a delegate. The value returned by the EventHandlerLis t
      indexer isn't type-safe, so it must be cast into the appropriate delegate
      Type, as you can see in the code above.
      >
      >I'm certain I'm right, I can see plenty of alternative ways of doing it
      >that would work, I'm just confused about the information I'm getting
      >off the internet.
      >So am I being fed porkies? Do Windows Forms controls use
      >EventHandlerLi st objects and if so how come their implementation allows
      >for += and the one in ComponentModel doesn't?
      >
      An EventHandlerLis t instance is exposed as a protected property named,
      "Events" from the Component class to all derived types. The "+=" operator
      acts on public events, not the "Events" property. The underlying
      implementation of "add" and "remove" on these public events can use the
      "Events" property, internally, to store the supplied delegate.
      >
      Yes, I'm sure WinForms controls use the Events property, though I'm not sure
      if ALL events on ALL WinForms Controls are registered through the inherited
      Component.Event s property. Web controls use the "Events" property as well,
      but it's declared in the base Control since Control doesn't derive from
      Component. It still works the same way.
      >
      In my example, the public event is "ServiceViewCha nged". The "add" and
      "remove" implementations of that event, which correspond to the "+=" and
      "-=" operators, respectively, add or remove the supplied delegate to or from
      the underlying EventHandlerLis t by calling either Events.AddHandl er or
      Events.RemoveHa ndler. Both of these methods require the same key used in
      the indexer when you attempt to retrieve the delegate reference from the
      list.
      >
      If things still aren't clear, let me know.
      >
      --
      Dave Sexton
      >
      >

      Comment

      • DeveloperX

        #4
        Re: EventHandlerLis t question (1.1)

        Thanks Dave, no problem on the Generics, I use 2 at home, 1.1 at work.
        There are some changes in 2 that affect Events in VB.net, so I
        specified 1.1 in case those changes were part of some underlying change
        in 2. I could of made that much much clearer :)

        Give me a while to digest the info and I'll let you know if I have any
        joy
        Cheers

        Dave Sexton wrote:
        Hi Ian,
        >
        Sorry about using C# generics - I just realized you wrote (1.1) in the title.
        >
        To be honest, I don't have a code snippet without generics on hand anyway. If
        you need me to rewrite my example without generics I will - just let me know.
        >
        --
        Dave Sexton
        >
        "Dave Sexton" <dave@jwa[remove.this]online.comwrote in message
        news:%23xyoZP4A HHA.3380@TK2MSF TNGP04.phx.gbl. ..
        Hi Ian,

        <snip>
        I was under the impression that
        windows.forms controls used EventHandlerLis ts because generally most
        events aren't consumed so this saves memory.
        True.
        I can add a button to a form, and have
        >
        this.button9.Cl ick += new System.EventHan dler(this.butto n9_Click);
        this.button9.Cl ick += new System.EventHan dler(this.butto n9b_Click);
        >
        which will successfully fire off both functions when the button is
        clicked.
        >
        The EventHandlerLis t does not fire both as it keys the delegate in a
        hashtable and overwrites the first reference with the second reference
        (This is using AddHandler).
        Here's an example that I'm using from a project I'm working on right now in
        a class that derives from Component:

        private readonly object ServiceViewChan gedEvent = new object();

        public event EventHandler<Se rviceViewChange dEventArgsServi ceViewChanged
        {
        add
        {
        lock (ServiceViewCha ngedEvent)
        {
        Events.AddHandl er(ServiceViewC hangedEvent, value);
        }
        }
        remove
        {
        lock (ServiceViewCha ngedEvent)
        {
        Events.RemoveHa ndler(ServiceVi ewChangedEvent, value);
        }
        }
        }

        private void OnServiceViewCh anged(ServiceVi ewChangedEventA rgs e)
        {
        EventHandler<Se rviceViewChange dEventArgshandl er = null;

        lock (ServiceViewCha ngedEvent)
        {
        handler = (EventHandler<S erviceViewChang edEventArgs>)
        Events[ServiceViewChan gedEvent];
        }

        if (handler != null)
        handler(this, e);
        }
        More confusingly in trying to get the thing running I see code all over
        the internet that can't run. A VB example that used a foreach (there's
        no enumerator so that can't work) and a C++ example where the
        EventHandlerLis t returns an EventHandler (It only returns Delegates in
        my tests)
        EventHandler is a delegate. The value returned by the EventHandlerLis t
        indexer isn't type-safe, so it must be cast into the appropriate delegate
        Type, as you can see in the code above.
        I'm certain I'm right, I can see plenty of alternative ways of doing it
        that would work, I'm just confused about the information I'm getting
        off the internet.
        So am I being fed porkies? Do Windows Forms controls use
        EventHandlerLis t objects and if so how come their implementation allows
        for += and the one in ComponentModel doesn't?
        An EventHandlerLis t instance is exposed as a protected property named,
        "Events" from the Component class to all derived types. The "+=" operator
        acts on public events, not the "Events" property. The underlying
        implementation of "add" and "remove" on these public events can use the
        "Events" property, internally, to store the supplied delegate.

        Yes, I'm sure WinForms controls use the Events property, though I'm not sure
        if ALL events on ALL WinForms Controls are registered through the inherited
        Component.Event s property. Web controls use the "Events" property as well,
        but it's declared in the base Control since Control doesn't derive from
        Component. It still works the same way.

        In my example, the public event is "ServiceViewCha nged". The "add" and
        "remove" implementations of that event, which correspond to the "+=" and
        "-=" operators, respectively, add or remove the supplied delegate to or from
        the underlying EventHandlerLis t by calling either Events.AddHandl er or
        Events.RemoveHa ndler. Both of these methods require the same key used in
        the indexer when you attempt to retrieve the delegate reference from the
        list.

        If things still aren't clear, let me know.

        --
        Dave Sexton

        Comment

        • DeveloperX

          #5
          Re: EventHandlerLis t question (1.1)


          Dave Sexton wrote:
          Hi Ian,
          >
          Sorry about using C# generics - I just realized you wrote (1.1) in the title.
          >
          To be honest, I don't have a code snippet without generics on hand anyway. If
          you need me to rewrite my example without generics I will - just let me know.
          >
          --
          Dave Sexton
          >
          "Dave Sexton" <dave@jwa[remove.this]online.comwrote in message
          news:%23xyoZP4A HHA.3380@TK2MSF TNGP04.phx.gbl. ..
          Hi Ian,

          <snip>
          I was under the impression that
          windows.forms controls used EventHandlerLis ts because generally most
          events aren't consumed so this saves memory.
          True.
          I can add a button to a form, and have
          >
          this.button9.Cl ick += new System.EventHan dler(this.butto n9_Click);
          this.button9.Cl ick += new System.EventHan dler(this.butto n9b_Click);
          >
          which will successfully fire off both functions when the button is
          clicked.
          >
          The EventHandlerLis t does not fire both as it keys the delegate in a
          hashtable and overwrites the first reference with the second reference
          (This is using AddHandler).
          Here's an example that I'm using from a project I'm working on right now in
          a class that derives from Component:

          private readonly object ServiceViewChan gedEvent = new object();

          public event EventHandler<Se rviceViewChange dEventArgsServi ceViewChanged
          {
          add
          {
          lock (ServiceViewCha ngedEvent)
          {
          Events.AddHandl er(ServiceViewC hangedEvent, value);
          }
          }
          remove
          {
          lock (ServiceViewCha ngedEvent)
          {
          Events.RemoveHa ndler(ServiceVi ewChangedEvent, value);
          }
          }
          }

          private void OnServiceViewCh anged(ServiceVi ewChangedEventA rgs e)
          {
          EventHandler<Se rviceViewChange dEventArgshandl er = null;

          lock (ServiceViewCha ngedEvent)
          {
          handler = (EventHandler<S erviceViewChang edEventArgs>)
          Events[ServiceViewChan gedEvent];
          }

          if (handler != null)
          handler(this, e);
          }
          More confusingly in trying to get the thing running I see code all over
          the internet that can't run. A VB example that used a foreach (there's
          no enumerator so that can't work) and a C++ example where the
          EventHandlerLis t returns an EventHandler (It only returns Delegates in
          my tests)
          EventHandler is a delegate. The value returned by the EventHandlerLis t
          indexer isn't type-safe, so it must be cast into the appropriate delegate
          Type, as you can see in the code above.
          I'm certain I'm right, I can see plenty of alternative ways of doing it
          that would work, I'm just confused about the information I'm getting
          off the internet.
          So am I being fed porkies? Do Windows Forms controls use
          EventHandlerLis t objects and if so how come their implementation allows
          for += and the one in ComponentModel doesn't?
          An EventHandlerLis t instance is exposed as a protected property named,
          "Events" from the Component class to all derived types. The "+=" operator
          acts on public events, not the "Events" property. The underlying
          implementation of "add" and "remove" on these public events can use the
          "Events" property, internally, to store the supplied delegate.

          Yes, I'm sure WinForms controls use the Events property, though I'm not sure
          if ALL events on ALL WinForms Controls are registered through the inherited
          Component.Event s property. Web controls use the "Events" property as well,
          but it's declared in the base Control since Control doesn't derive from
          Component. It still works the same way.

          In my example, the public event is "ServiceViewCha nged". The "add" and
          "remove" implementations of that event, which correspond to the "+=" and
          "-=" operators, respectively, add or remove the supplied delegate to or from
          the underlying EventHandlerLis t by calling either Events.AddHandl er or
          Events.RemoveHa ndler. Both of these methods require the same key used in
          the indexer when you attempt to retrieve the delegate reference from the
          list.

          If things still aren't clear, let me know.

          --
          Dave Sexton
          You were spot on with the assertion that I needed to cast the Delegate
          to the correct type. I had previously attempted to cast it to an
          EventHandler with didn't work. The reason being I was using an example
          borrowed from MS which uses MouseEventHandl er (Their code only went as
          far as adding the delegate to the list not firing it).

          I now have it working both by deriving from Component and using Events,
          and with a EventHandlerLis t declared in the class.

          Thanks for your help
          Ian

          Comment

          Working...