Search code examples
c#keypresskeydown

How to handle Keydown event in Form level after All Child controls handled it?


I have a form with two controls A and B , A has a key-down event and i show a message box when 'S' is pressed on A control. And i want to show another message when 'S' is pressed in any other control.

how can I do this ?

Simply what I want is : I should be able to handle a Key-down event after all child controls. and I should be able to know whether the Event is handle in a child control in Form-level Key-down.

I tried enabling Key-preview but when Key-preview is enabled Form-level event get's fired before child control events. I want child controls first, Then Form level one

I want form level Event to be fired after focused control's key down event is fired. and I want to check in Form-level event whether the event is handled in focused controls key-down event.

What methods can I use for this ?

Please enlighten me.


Solution

  • you can do the following

    here a sample code

    1. Add new project call it EventSample
    2. Add a UserControl call it AControl
    3. Add a UserControl call it BControl
    4. make the AControl BackColor Blue and BControl Red in order to distinguish from the form

    //Form1 code

    namespace EventSample
    {
        public delegate void AfterChildEventHandler(Control control,Keys key);
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                aControl1.OnChildFireEvent += OnChildFireEvent;
                bControl1.OnChildFireEvent += OnChildFireEvent;
            }
    
            void OnChildFireEvent(Control control, Keys key)
            {
                MessageBox.Show("Form fired event from " + control.GetType().Name);
            }
        }
    }
    

    //AControl code

    namespace EventSample
    {
        public partial class AControl : UserControl
        {
            public event AfterChildEventHandler OnChildFireEvent;
            public AControl()
            {
                InitializeComponent();
            }
    
            private void AControl_KeyDown(object sender, KeyEventArgs e)
            {
                MessageBox.Show("A Control fired Key down");
                if (OnChildFireEvent != null)
                    OnChildFireEvent(this, e.KeyCode);
            }
        }
    }
    

    //BControl code

    public partial class BControl : UserControl
        {
            public event AfterChildEventHandler OnChildFireEvent;
            public BControl()
            {
                InitializeComponent();
            }
    
            private void BControl_KeyDown(object sender, KeyEventArgs e)
            {
                MessageBox.Show("B Control fired Key down");
                if (OnChildFireEvent != null)
                    OnChildFireEvent(this, e.KeyCode);
            }
        }
    

    EDITED

    another solution you can make it with less code

    1. define a static event
    2. handle this event inside the form
    3. let each control to invoke this event

      namespace EventSample {

      public delegate void AfterChildEventHandler(Control control, Keys key);
      
      public class GlobalEvent
      {
          public static event AfterChildEventHandler OnChildEventFire;
      
          public static void Invoke(Control control, Keys key)
          {
              if (OnChildEventFire != null)
                  OnChildEventFire(control, key);
          }
      }
      

      }

    changes in the A Control

    namespace EventSample
    {
        public partial class AControl : UserControl
        {
            public AControl()
            {
                InitializeComponent();
            }
    
            private void AControl_KeyDown(object sender, KeyEventArgs e)
            {
                MessageBox.Show("A Control fired Key down");
                GlobalEvent.Invoke(this, e.KeyCode);
            }
        }
    }
    

    changes in the B Control

    namespace EventSample
    {
        public partial class BControl : UserControl
        {
            public BControl()
            {
                InitializeComponent();
            }
    
            private void BControl_KeyDown(object sender, KeyEventArgs e)
            {
                MessageBox.Show("B Control fired Key down");
                GlobalEvent.Invoke(this, e.KeyCode);
            }
        }
    }
    

    Build the sample and run and try to press any key on A or B then you will find that A will fire then the form

    hope it will help you