Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C# User-controls Events
Hello,
 
I have 3 user controls:
 
1) smallControl.
This control sends events when the user clicks on it:
 
partial class smallControl
{
...
   public delegate void SendControlClickedNotification(Object sender);
   public event SendControlClickedNotification ControlClickedNotification;
 
      protected virtual void OnControlClicked()
      {
         if (ControlClickedNotification != null)
            ControlClickedNotification(this);
      }
 
2) arrayControl.
This control can add several smallControls to an array. When a smallControl is added, the arrayControl is being registered to the ControlClickedNotification event of the smallControl:
 
   public class arrayControl
   {
     public void AddControl()
     {
       smallControl smallControlElement = new smallControl();
 
       smallControlElement .ControlClickedNotification += new SendControlClickedNotification(smallControlElement _Click);
 
       this.Add(smallControlElement);
 
     }
 }
 

3) Container Control. This control contains 2 things:
an arrayControl, and a pictureBox.
 
I want the pictureBox to be registered to the events of SendControlClickedNotification (whenever a smallControl is clicked, I want the picture box to get the notification).
 
How can I do it?
Posted 23-Oct-12 0:26am
Edited 23-Oct-12 0:27am
digimanus30.8K
v2
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

All your questions are reduced to a simple thing: you compose some children controls in some parent controls and want to introduce and expose some new events at the level of parent control, as the children are apparently hidden from the used of the user control.
 
There is nothing special in this situation. You simply need to work "by definition": add an event handler to the invocation list of some child's event; in the handler implementation, invoke the parent's event. Lets look at it on the simple example of one child and its Click event:
 
public class ChildEventArgs : System.EventArgs {
    internal ChildEventArgs(Control child) { this.Child = child; } // don't do it public: the user only handles it
    public Child { get { return this.child; } }
    Control child;
}
 
public partial class MyParentControl {
    public MyParentControl() {
        child.Click += (sender, eventArgs) => {
             if (ChildClicked != null)
                 ChildClicked.Invoke(this, new ChildEventArgs(child));
        };
        //...
        Controls.AddChild(child);
    }
    public event System.EventHandler<ChildEventArgs> ChildCliked;
    SomeControlType child = new SomeControlType();
}
 
For an array (but it should be some collection instead, I presume), you basically do the same, but dynamically. Most likely, you need to add the handler to the invocation lists of children events when you add a child, but in this case, you will also need to remove a handler ("-="), to cover rare cases when a child is removed but still used outside of your control, can be added again, etc., so you would avoid multiple handlers. You can also develop special children control types to improve it. I'll leave all that for your home exercise. Smile | :)
 
—SA
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

I want to add a side-note answer related to your first code fragment. The recommended practice is different: to use two parameters in the delegate type always: first one being System.Object, second one — of the type derived from System.EventArgs:
 
public SmallControlEventArgs : System.EventArgs //...

// as base class/interfaces are not shown, could only be partial:
partial partial class SmallControl { // casing improved to meet (good) Microsoft naming conventions
   public event System.EventHandler<SmallControlEventArgs> ControlClickedNotification;
   //...
}
 
I don't want to say that you are absolutely required to do so: in such simple cases like Click one or two parameters are redundant. However, there are many cases when they are useful — please see Solution 1. If you use FxCop to validate your code, it will, be default rules, require following the pattern shown.
 
Please see:
http://msdn.microsoft.com/en-us/library/system.eventargs.aspx[^],
http://en.wikipedia.org/wiki/FxCop[^],
http://msdn2.microsoft.com/en-us/library/bb429476.aspx[^].
 
I would prefer to say, it's up to you; it's not required be syntax and general event functionality. But I personally always follow the recommended pattern, so far. Smile | :)
 
—SA
  Permalink  

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 6,045
1 DamithSL 4,601
2 Maciej Los 4,087
3 Kornfeld Eliyahu Peter 3,480
4 Sergey Alexandrovich Kryukov 3,310


Advertise | Privacy | Mobile
Web04 | 2.8.141220.1 | Last Updated 23 Oct 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100