locked
Firing an event on another form RRS feed

  • Question

  • Hi,

    I have a form, containing a button, which lauches a User Control to be popped up. So, for simplicity's sake, how do I fire off an event, or method/function on the form after clicking the close button of the user control?
    Thursday, April 2, 2009 5:33 AM

Answers

  • class SecondFormWithUserControl
    {
      private FirstForm firstForm;
    
      public SecondForm()
      {
        InitializeComponent();
        // this means unregistering on form closing, uncomment if is necessary (anonymous delegate)
        //this.Form_Closing += delegate { firstForm.SomeEvent -= SecondForm_SomeMethod; };
      }
    
      public SecondaryForm(FirstForm form) : this()
      {
        this.firstForm = form; 
        firstForm.Timer.Tick += new EventHandler(Timer_Tick);
      }
    
      // make it public in case of external event handlers registration
      private void Timer_Tick(object sender, EventArgs e)
      {
        // now you can access firstForm or it's timer here
      }
    }
    
    class FirstForm
    {
      public Timer Timer
      {
        get
        {
          return this.the_timerl
        }
      }
    
      public FirstForm()
      {
        InitializeComponent();
      }
    
      private void Button_Click(object sender, EventArgs e)
      {
        new SecondFormWithUserControl(this).ShowDialog(); // in case of internal event handlers registration (in constructor)
        // or
        SecondFormWithUserControl secondForm = new SecondFormWithUserControl(this);
        the_timer.Tick += new EventHandler(secondForm.Timer_tick); // that method must be public
      }
    
    

    Instead of timer_tick event.

    Handle the formclosing event of SecondForm
    Thanks, A.m.a.L | [Remember to click "mark as answered" when you get a correct reply to your question]
    • Marked as answer by Kira Qian Wednesday, April 8, 2009 5:52 AM
    Thursday, April 2, 2009 5:54 AM
  • Hi Dr. Cidolfus,

    Base on my understanding, you want to hang form1 until the OK button is clicked and the DialogResult.OK is return.

    I don't think you can do it outside form1, when if (f.DialogResult == DialogResult.OK) is false, f.Close() won't be run, but the form1 already closed. So you cannot use this way to hang a form.

    The easiest way I know is handle the FormClosing event. And you can create a base form for your project. This form have an Close button, you can only close that form with your "Close" button.
    public partial class BaseForm : Form
        {
            private bool canClose;

            public BaseForm()
            {
                InitializeComponent();
                canClose = false;
                this.FormClosing += new FormClosingEventHandler(BaseForm_FormClosing);
            }

            void BaseForm_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (canClose == false)
                {
                    e.Cancel = true;
                }
            }

            private void btnClose_Click(object sender, EventArgs e)
            {
                canClose = true;
                this.Close();
            }
        }
    When you need this restrict for a form, you can inherite that form from BaseForm. I think that can solve yor problem.

    Sincerely,
    Kira Qian


    Please mark the replies as answers if they help and unmark if they don't.
    • Marked as answer by Louis Leong Friday, April 10, 2009 4:00 PM
    Friday, April 3, 2009 8:44 AM
  • Hi Dr.Cidolfus,


    I tried your code, and also created a second Form, which should be closed from the first one - as you mentioned.

    So what I have is:

    Form1 - main form. calls the other forms
    Form2 - child form. Your UserControl . Has a button which signalizes to Form1 , that its time to Close.

    What I did was to add an event in Form2 called IamClosed . This event is fired, when you click your button in Form2.

    public partial class Form2 : Form
    {
        //Add an event, which signalizes for e.g. closing!
        public delegate void IamClosed(object sender);
        public event IamClosed OnIamClosed;
    
        //Standard Code
        public Form2()
        {
            InitializeComponent();
        }
    
        //When the button is clicked
        private void Button_CloseForm2_Click(object sender, EventArgs e)
        {
            //fire event to parent form.
            OnIamClosed(this);
        }
    }
    
     


    Now in the parent form, Form1 , I modified your code to accomodate this event and its firing.

    //THIS IS PART OF FORM1
    
    //define form2
    Form2 f;
    
    //in some function...maybe a button click...initialize Form2
    f = new Form2();
    
    //Add its event
    f.OnIamClosed += new Form2.IamClosed(form2_OnIamClosed);
    
    //and show it.
    f.ShowDialog(this);
    
    
    //fired event's handling function
    void form2_OnIamClosed(object sender)
    {
        //Close the form, if you wish to!
        f.Close();
        //Do other stuff here
    }
    
     

    Of course, this method can be used on UserControl as well. I just took a form for simplicity sake.

    Hope this helps!



    If the reply answers your question, please mark it as Answer, or Helpful, if it helped! Thanks!
    • Edited by BA_Newbie Friday, April 3, 2009 9:07 AM C# compatible
    • Proposed as answer by BA_Newbie Tuesday, April 7, 2009 7:41 AM
    • Marked as answer by Kira Qian Wednesday, April 8, 2009 5:52 AM
    Friday, April 3, 2009 9:02 AM

All replies

  • can you explain a bit detail.
    Thanks, A.m.a.L | [Remember to click "mark as answered" when you get a correct reply to your question]
    Thursday, April 2, 2009 5:37 AM
  • Let me rephrase that, and be a little more specific.

    In a button event of my MainForm, I have this:

    Form1 f = new Form1();
    f.ShowDialog(this);
    if (f.DialogResult == DialogResult.OK)
    {
    	f.Close();
    	//Do other stuff here
    }
    Doing this with forms, the codes in the IF segment won't fire until I've clicked on the button of Form1 that sends the DialogResult.OK back to MainForm,
    so instead of using Form1, now I have UserControl1, which doesn not support DialogResult I believe, so how can I achieve the same result with UserControls?
    Thursday, April 2, 2009 5:43 AM
  • You have:
    - Form(1) with button, clicking button opens the user control that is on another Form(2)
    - Clicking user control close button will close the Form(2).


    Now what exactly you want to achieve?
    - Do you want that the Form(1) will know when the Form(2) closed?
    - Or what?
    Tomi Airaksinen - MCPD [Remember to click "mark as answered" when you get a correct reply to your question]
    Thursday, April 2, 2009 5:45 AM
  • class SecondFormWithUserControl
    {
      private FirstForm firstForm;
    
      public SecondForm()
      {
        InitializeComponent();
        // this means unregistering on form closing, uncomment if is necessary (anonymous delegate)
        //this.Form_Closing += delegate { firstForm.SomeEvent -= SecondForm_SomeMethod; };
      }
    
      public SecondaryForm(FirstForm form) : this()
      {
        this.firstForm = form; 
        firstForm.Timer.Tick += new EventHandler(Timer_Tick);
      }
    
      // make it public in case of external event handlers registration
      private void Timer_Tick(object sender, EventArgs e)
      {
        // now you can access firstForm or it's timer here
      }
    }
    
    class FirstForm
    {
      public Timer Timer
      {
        get
        {
          return this.the_timerl
        }
      }
    
      public FirstForm()
      {
        InitializeComponent();
      }
    
      private void Button_Click(object sender, EventArgs e)
      {
        new SecondFormWithUserControl(this).ShowDialog(); // in case of internal event handlers registration (in constructor)
        // or
        SecondFormWithUserControl secondForm = new SecondFormWithUserControl(this);
        the_timer.Tick += new EventHandler(secondForm.Timer_tick); // that method must be public
      }
    
    

    Instead of timer_tick event.

    Handle the formclosing event of SecondForm
    Thanks, A.m.a.L | [Remember to click "mark as answered" when you get a correct reply to your question]
    • Marked as answer by Kira Qian Wednesday, April 8, 2009 5:52 AM
    Thursday, April 2, 2009 5:54 AM
  • public partial class UserControl1 : UserControl
        {
            public delegate void EventHandler(Object sender, EventArgs e);
            public event EventHandler OnCloseClickEventHandler;
    
    
            public UserControl1()
            {
                InitializeComponent();
            }
    
            private void buttonClose_Click(object sender, EventArgs e)
            {
                if (OnCloseClickEventHandler != null)
                {
                    // Fire event.
                    OnCloseClickEventHandler(this, new EventArgs());
                }
            }
        }
    
    // This form has the user control on it.
        public partial class Form2 : Form
        {
            public Form2()
            {
                InitializeComponent();
    
                this.DialogResult = DialogResult.Cancel;
                this.userControl11.OnCloseClickEventHandler += new UserControl1.EventHandler(userControl11_OnCloseClickEventHandler);
            }
    
            void userControl11_OnCloseClickEventHandler(object sender, EventArgs e)
            {
                this.DialogResult = DialogResult.OK;
                this.Close();
            }
        }
    
    

    Tomi Airaksinen - MCPD [Remember to click "mark as answered" when you get a correct reply to your question]
    Thursday, April 2, 2009 6:02 AM
  • Hi Dr. Cidolfus,

    Base on my understanding, you want to hang form1 until the OK button is clicked and the DialogResult.OK is return.

    I don't think you can do it outside form1, when if (f.DialogResult == DialogResult.OK) is false, f.Close() won't be run, but the form1 already closed. So you cannot use this way to hang a form.

    The easiest way I know is handle the FormClosing event. And you can create a base form for your project. This form have an Close button, you can only close that form with your "Close" button.
    public partial class BaseForm : Form
        {
            private bool canClose;

            public BaseForm()
            {
                InitializeComponent();
                canClose = false;
                this.FormClosing += new FormClosingEventHandler(BaseForm_FormClosing);
            }

            void BaseForm_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (canClose == false)
                {
                    e.Cancel = true;
                }
            }

            private void btnClose_Click(object sender, EventArgs e)
            {
                canClose = true;
                this.Close();
            }
        }
    When you need this restrict for a form, you can inherite that form from BaseForm. I think that can solve yor problem.

    Sincerely,
    Kira Qian


    Please mark the replies as answers if they help and unmark if they don't.
    • Marked as answer by Louis Leong Friday, April 10, 2009 4:00 PM
    Friday, April 3, 2009 8:44 AM
  • Hi Dr.Cidolfus,


    I tried your code, and also created a second Form, which should be closed from the first one - as you mentioned.

    So what I have is:

    Form1 - main form. calls the other forms
    Form2 - child form. Your UserControl . Has a button which signalizes to Form1 , that its time to Close.

    What I did was to add an event in Form2 called IamClosed . This event is fired, when you click your button in Form2.

    public partial class Form2 : Form
    {
        //Add an event, which signalizes for e.g. closing!
        public delegate void IamClosed(object sender);
        public event IamClosed OnIamClosed;
    
        //Standard Code
        public Form2()
        {
            InitializeComponent();
        }
    
        //When the button is clicked
        private void Button_CloseForm2_Click(object sender, EventArgs e)
        {
            //fire event to parent form.
            OnIamClosed(this);
        }
    }
    
     


    Now in the parent form, Form1 , I modified your code to accomodate this event and its firing.

    //THIS IS PART OF FORM1
    
    //define form2
    Form2 f;
    
    //in some function...maybe a button click...initialize Form2
    f = new Form2();
    
    //Add its event
    f.OnIamClosed += new Form2.IamClosed(form2_OnIamClosed);
    
    //and show it.
    f.ShowDialog(this);
    
    
    //fired event's handling function
    void form2_OnIamClosed(object sender)
    {
        //Close the form, if you wish to!
        f.Close();
        //Do other stuff here
    }
    
     

    Of course, this method can be used on UserControl as well. I just took a form for simplicity sake.

    Hope this helps!



    If the reply answers your question, please mark it as Answer, or Helpful, if it helped! Thanks!
    • Edited by BA_Newbie Friday, April 3, 2009 9:07 AM C# compatible
    • Proposed as answer by BA_Newbie Tuesday, April 7, 2009 7:41 AM
    • Marked as answer by Kira Qian Wednesday, April 8, 2009 5:52 AM
    Friday, April 3, 2009 9:02 AM