How to raise event in another form

  • (2 Pages)
  • +
  • 1
  • 2

15 Replies - 19118 Views - Last Post: 20 April 2011 - 09:00 AM Rate Topic: -----

#1 kjell.liljegren@hotmail.co  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 19-April 11

How to raise event in another form

Posted 19 April 2011 - 11:37 AM

Hi

I'm trying to figure out how to raise an event in another form.

this is my app: MDI-windows application that can load several unique child-forms.

One of these Child forms holds a listview contaning "items"

I can load a dialog form (.showDialog) either from the Child form or directly from the MDI, when loading from the child form I have no problem to take action in that form based on the input given in the dialog.

But, here is my problem, when loading the dialog from the MDI-form I need to "tell" the Child form that the listview is no longer correct, so it can reload its content.
this is where I need to raise an event in that Child form.
I have very little experience with "custom events" so I have no clue what to do to accomplish this.


Kjell

Is This A Good Question/Topic? 0
  • +

Replies To: How to raise event in another form

#2 lordofduct  Icon User is offline

  • I'm a cheeseburger
  • member icon


Reputation: 2538
  • View blog
  • Posts: 4,641
  • Joined: 24-September 10

Re: How to raise event in another form

Posted 19 April 2011 - 11:39 AM

verbage may be throwing you off...

the MDI parent doesn't have to raise an event in the child. That's like saying... "Hey kid, yell out that I told you to yell out so I know that I told you to yell out."

Just have a method available on the child form to clean the display...

//in child form
public void CleanComboListView()
{
    //reset here
}



then just call it when necessary.


If you want the child form to still raise an event for whatever reason (maybe something else is listening to it other than the MDI parent), then raise said event in this method. But I don't think this is necessary for what you're attempting to accomplish.

This post has been edited by lordofduct: 19 April 2011 - 11:42 AM

Was This Post Helpful? 0
  • +
  • -

#3 Curtis Rutland  Icon User is offline

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4577
  • View blog
  • Posts: 8,019
  • Joined: 08-June 10

Re: How to raise event in another form

Posted 19 April 2011 - 11:44 AM

If you do end up needing to raise one event to another form, we have a link in our C# Resources Thread that will help:

http://www.dreaminco...ny-other-forms/

In it, I discuss custom events and handling them from other forms, in the Modeless section.
Was This Post Helpful? 0
  • +
  • -

#4 kjell.liljegren@hotmail.co  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 19-April 11

Re: How to raise event in another form

Posted 19 April 2011 - 11:53 AM

I'm having problem to do it like you say, let me add som details..

In my MDI-form i do something like this:

private void addNewTaskToolStripMenuItem_Click(object sender, EventArgs e)
    {
            DlgRegNewTask AddTaskFrm = new DlgRegNewTask(false);

            AddTaskFrm.ShowDialog();
            
            if (AddTaskFrm.DlgWasCanceled)
            { AddTaskFrm.Dispose(); return; }

           //this is where my problem come in
          
    }
I know need to "tell" a childform that might or might not be loaded
if its loaded it listcontent is no longer valid
This Child can be found using a loop through all loaded forms
But I can still not call a function in the form.
Have I missed something?
this is why I was into the ide to raise an event via a delegate
or some other way

This post has been edited by Curtis Rutland: 19 April 2011 - 12:31 PM

Was This Post Helpful? 0
  • +
  • -

#5 kjell.liljegren@hotmail.co  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 19-April 11

Re: How to raise event in another form

Posted 19 April 2011 - 12:03 PM

I applogise for my poor english, lots of missspelled words...

I tried this, but this is not possible to do
Is there any other way to get a object reference to a loaded form?
so one can call a function within that form (non-static function)

foreach (Form childForm in Application.OpenForms)
                {
                    if (childForm.Tag != null)
                    {
                        if (childForm.Tag.ToString() == "MainTaskList")
                        {
                            
                            childForm.xxxxxx    //this is not possible to do to call a function
                           
                        }
                    }
                }






Kjell
Was This Post Helpful? 0
  • +
  • -

#6 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5676
  • View blog
  • Posts: 12,194
  • Joined: 02-June 10

Re: How to raise event in another form

Posted 19 April 2011 - 12:05 PM

What you have missed is that you aren't supposed to be directly calling methods in another form.

Your main form should raise an event.
The other form should 'hear' that event the do what it needs to.
The other form then raises an event saying 'I'm done'.
Your main form then knows it is complete.

Having form1 so tightly bound to form2 that it needs to micromanage it and tell it every last thing to do, and in what order is just bad programming and is frowned upon.

The tutorials below walk through making an application including inheritance, custom events and custom controls.
Quick and easy custom events
Bulding an application - Part 1
Building an application - Part 2
Passing values between forms/classes

This post has been edited by tlhIn`toq: 19 April 2011 - 12:06 PM

Was This Post Helpful? 1
  • +
  • -

#7 Curtis Rutland  Icon User is offline

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4577
  • View blog
  • Posts: 8,019
  • Joined: 08-June 10

Re: How to raise event in another form

Posted 19 April 2011 - 12:31 PM

Quote

What you have missed is that you aren't supposed to be directly calling methods in another form.


I don't necessarily agree with this in a modal context, as we've discussed before. I think the question is, is MDI modal?
Was This Post Helpful? 1
  • +
  • -

#8 kjell.liljegren@hotmail.co  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 19-April 11

Re: How to raise event in another form

Posted 19 April 2011 - 12:45 PM

thanks tlhIn`toq

Like my topic says: Raise event


I think your first link actually contains the solution to my problem.
My job is now to read this sample, which is an excelent sample of a "custom event" implementation.
and figure out how to translate all bits and pieces to my application.

I will do this in the morning, it's almost bedtime here so I'll dedicate the rest of the evning to my family


Best regards to you all


Kjell
Was This Post Helpful? 0
  • +
  • -

#9 Curtis Rutland  Icon User is offline

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4577
  • View blog
  • Posts: 8,019
  • Joined: 08-June 10

Re: How to raise event in another form

Posted 19 April 2011 - 01:51 PM

Also, take a look at the tutorial I posted. It's not as in-depth about events as tlhintoq's is, but it shows it in the context of raising events from one form to another. It's in the "modeless" section.
Was This Post Helpful? 0
  • +
  • -

#10 kjell.liljegren@hotmail.co  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 19-April 11

Re: How to raise event in another form

Posted 20 April 2011 - 01:02 AM

Thank you tlhIn`toq, your link to your sample made my day :-)

My first attempt did not work and I would like to understand why.


this is what I did in attempt 1:

1. Created the 'TextArgs.cs' class from your sample
2. Added the 'void Feedback_Received(object sender, TextArgs e)'
into the child form that needs to be informed that something has changed.

3. Added the 'public event EventHandler<TextArgs> Feedback;' into the same child form
4. Added the 'Feedback += new EventHandler<TextArgs>(Feedback_Received);' into the same Child form in Form_Load

5. Added the 'private void RaiseFeedback(string p)' into the MDI-form
6. and finally added a call 'RaiseFeedback("MainTaskList");' upon exiting the .showDialog, still within the MDI.

Now, as you probably will say, point 3 & 4 is not correct, I had to remove these 2 and instead do:

In the MDI-form where I Instanciate the child form, add the 'Feedback +=......' as per below
MainTaskList MainT = new MainTaskList();
MainT.MdiParent = this;
Feedback += new EventHandler<TextArgs>(MainT.Feedback_Received);
MainT.Show();

and change the scoop of 'void Feedback_Received(.... into
'public void Feedback_Received'

then it worked :-)


Why was not the first attempt subscribing to the same event ('TextArgs') as declared in the MDI?
Is it simply because it was declared in the child form and therefor considered as another instance of the same 'TextArgs' class.

If I got this right: The MDI declares an 'Event' and can then "hand-over" a link to this 'Event' to anyone needing to stay in touch?
Is there any solution if you cannot 'hand-over' the link to a Form?, instead you need to "hook-on" to a 'possibly existing' Event somewhere in your application? If you understand the question...


Thanks for your time and effort, I'll now consider this problem as solved :-)


Kjell
Was This Post Helpful? 0
  • +
  • -

#11 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5676
  • View blog
  • Posts: 12,194
  • Joined: 02-June 10

Re: How to raise event in another form

Posted 20 April 2011 - 07:06 AM

The important thing is that it's working.

If I am following you, there isn't anything 'wrong' with lines 3 & 4 - it's just that it would do something different than your goal.

There is nothing wrong with having multiple subscriptions to the same event.

You can have the child subscribe to it's own Feedback event *in addition to* the parent having a subscription.

The idea here is that for the same Feedback event the child can do one thing like show the feedback in the status bar, and at the same time the parent will hear the feedback and do something different like write it to a log file.
Was This Post Helpful? 0
  • +
  • -

#12 Curtis Rutland  Icon User is offline

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4577
  • View blog
  • Posts: 8,019
  • Joined: 08-June 10

Re: How to raise event in another form

Posted 20 April 2011 - 07:14 AM

Quote

You can have the child subscribe to it's own Feedback event *in addition to* the parent having a subscription.


Though typically you wouldn't.

In most of the MSDN examples, the template looks like this:

public event EventHandler<SomeEventArgs> EventName;

protected virtual void OnEventName(/*parameters if necessary*/){
  //any code to do when triggered
  if(EventName != null)
    EventName(this, new SomeEventArgs(/*params*/));
}


It's protected and virtual so that if you extend the component, you can override the method that calls the event.

If you needed to handle something from within the client when the event is triggered, you'd do it there (in your example, the RaiseFeedback method is the same as this). There's no need to subscribe to the event in the class that defines it, because you can just handle it as it's raised, instead of listening for it being raised.
Was This Post Helpful? 0
  • +
  • -

#13 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5932
  • View blog
  • Posts: 12,855
  • Joined: 16-October 07

Re: How to raise event in another form

Posted 20 April 2011 - 07:37 AM

Simply, an event is a way to give notification when you don't know who you're notifying.

If an object creates another object, the parent knowns everything about the child object. The parent can call public methods of the child, read the state of the child, or delete the child.

The child has less control. It doesn't know who it's parents are ( all good OO children are bastards .) It doesn't know who to tell when it's wet itself. However, with an event, it can scream about something that just happened to everyone listening.

While the parent can read the child's state at any time, it doesn't have a way to know the state has just changed. It could look every milisecond, but that would be wasteful. Instead, the parent states that it will listen to the child's SomethingHappened event. The parent further states that when it hears the event, it will call a method of it's own do deal with it ( the format of the method is described by delegate ).

In short, events should be used when the audience is unknown. If you have a reference to an object that needs to know, you should just be able to tell that object.

You can use events to notify children if you don't want to maintain a list of children. However, for description purposes, that confuses the situation an event addresses, which is notifying unknown "observers."
Was This Post Helpful? 0
  • +
  • -

#14 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5676
  • View blog
  • Posts: 12,194
  • Joined: 02-June 10

Re: How to raise event in another form

Posted 20 April 2011 - 07:43 AM

MSDN does a lot of "do as we say, not as we do ourselves." For example they tell everyone else not to use the Registry but they have thousands of entries even in their most recent OS and product releases.

I think that's a matter of programming style.
Maybe it's right, maybe it's wrong, but I tend to subscribe to events even within the same class, such as Feedback. Mostly because I don't like mixing techniques when I have no real reason to besides MS telling me so. Oh here I subscribed but here I did it in the method. If I want something done then raise the event. If I see nothing is reacting then the event wasn't raised and I know where to start looking for an problem.

Generally all the subscriptions are set-up at the same point in code, such as a Form_load method. By subscribing to the event I find it easy to confirm the event is being raised. For example, a serial port PinChanged event might have two subscriptions: One to actually react to the single and another to blink a GUI LED. If I need to test something I had a subscription to a temporary method that opens a MessageBox. When I am done testing I comment-out the subscription.

I find it easier to use conditions and precompile directives to decide which events will be active. For example

#if VERBOSE
    this.Feedback += DisplayFeedbackInVerbosePallet();
#endif


If I compile with VERBOSE defined then I get all the feedback displayed in a special pallet. If I take out the directive then I don't. Without making any changes to the actual code anywhere.

If I need to stop listening for a bit then restart listening again its easy.

this.Dirty -= FormDirty();
LoadAllMySettings();// If I'm loading I don't need to mark the document dirty
this.Dirty += FormDirty(); //This component will now listen to it's own Dirty event as well as raise it for the parent to hear.


Again, I think its a matter of style and habits we fall into.
Was This Post Helpful? 0
  • +
  • -

#15 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5676
  • View blog
  • Posts: 12,194
  • Joined: 02-June 10

Re: How to raise event in another form

Posted 20 April 2011 - 07:57 AM

Nicely said baavgai, though I would modify it slightly. Instead of

baavgai said:

Simply, an event is a way to give notification when you don't know who you're notifying.

I would say

Quote

Simply, an event is a way to give notification when you don't care who you're notifying.

Because you can know all of the player, yet still choose to yell to the collective and not talk individually and personally to each one.

I would also point out that the child-notify-parent model isn't the only place this works. It also works well for sibling-notify-sibling situations.

If myForm1 (parent) creates myForm2, myForm3, myForm4 children instance then the parent myForm1 knows all of it's children and has the power to cross-wire events and handlers.

within myForm1:
myForm2.DoneLoading += myForm3.LoadCompleteHandler();
myForm2.DoneLoading += myForm4.LoadCompleteHandler();
myForm2.RequestClose += myForm3.BeginShutdown();
myForm2.RequestClose += myForm4.BeginShutdown();
myForm3.ShutdownComplete += myForm2.SiblingClosedHandler();
myForm4.ShutdownComplete += myForm2.SiblingClosedHandler();


Here we see how the parent can wire the children to talk to each other and leave the parent out of the conversations.
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2