Link to home
Start Free TrialLog in
Avatar of San24
San24

asked on

Events on the Main form, User Control - Communication

Experts,

Whats the best way to communicate between events on the Main form and events on a User Control.

Let me explain -

I have a set of Tabs in a Tab Control. Each Tab is a separate file and consists of a User Control. The User Control itself contains a Sub Tab Control and has other User Controls with events within its Tab pages. Lets say a simple Button click on each User Control within a Tab page, when the user clicks on the Button, I need to check if there is filename associated with the Main Tab. If it does not have a file name, I need to show a Save File Dialog. And give the Tab a file name. I want the Save Dialog only if there is no Filename for the Tab opened.

Now, the Main form has Menu Items with [Save, Save As..etc] When I click on Save As the Save File Dialog needs to open. And the Tab gets a new file name.

Now lets say, the user Saves the file first thrrough the Save As menu item and then Clicks the Button on the User Control, then there is no Save File Dialog cause there is already a Filename associated with the tab.

How do I get access to the filename from both the Menu Item event and the User Control event, so that I can keep track to show the Save File Dialog.

What is the best approach, keeping in mind I need to do other events like Open, Save file while closing events etc. I

Thanks!



Avatar of San24
San24

ASKER

Bubbling of Events? Is that the way to go?
SOLUTION
Avatar of alexey_gusev
alexey_gusev
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of San24

ASKER

Alexey,

Thats just bubbling of events right? oris it something different .. Callback? Can you give me a simple example.

Avatar of San24

ASKER

Idle Mind,

Exactly - since there are two kinds of communication needed, I was wondering what would be the best way to approach this. So I have to implement two way communication right?

If I had used MDI Parent forms, I didn`t have to do all this.

Let me play with your solution and I`ll let you know how it works out.
"If I had used MDI Parent forms, I didn`t have to do all this."

I disagree, both points still apply to Mdi apps as well.

You have to communicate "in" from the MdiParent to the children.
You have to communicate "out" from the MdiChildren to the MdiParent form.
Avatar of San24

ASKER

Interesting. I haven`t used MDI Forms, but read that the parent keeps track of its open and active children. I so I was guessing the communication wa done internally. I should have known before I spoke, sorry about that.
It does keep track of the open MdiChildren in a collection and also gives you the ability to grab the current active MdiChild but it doesn't help any further than that since it doesn't know what you want to do with those children...  ;)

The children are still custom forms with their own sets of controls on them.  It's up to you to decide how they communicate with each other.
Avatar of San24

ASKER

Bubbling of Event  - What am I missing here? Is this the right way to do it?

I`m getting an Error  "An object reference is needed for non static field, method or property"

 //User Control File - SubUserCntrl
 public event EventHandler MyCusEvent;

        public SubUserCntrl()
        {
            InitializeComponent();
            Dock = DockStyle.Fill;      
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (MyCusEvent != null)
                MyCusEvent(this, e);        
        }
           
//InitializeComponent() of Form1

SubUserCntrl.MyCusEvent += new System.EventHandler(MyCusEvent);

//Form1.cs
//Everytime I click the button1 on SubUserCntrl - Is the function below called?
 private void MyCusEvent(object sender, EventArgs e)
        {
         //Do Something here
            MessageBox.Show("Test");
        }
It works for me:

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            subUserCntrl1.MyCusEvent += new EventHandler(subUserCntrl1_MyCusEvent);
        }

        void subUserCntrl1_MyCusEvent(object sender, EventArgs e)
        {
            MessageBox.Show("Test");
        }
    }

    public partial class SubUserCntrl : UserControl
    {
        public event EventHandler MyCusEvent;

        public SubUserCntrl()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (MyCusEvent != null)
                MyCusEvent(this, e);        
        }
    }
Avatar of San24

ASKER

Idle Mind,

Do I have to create a new instance of the User Control

 subUserCntrl subUserCntrl1 = new subUserCntrl();

    public partial class Form1 : Form
    {
     
        // ????
        subUserCntrl subUserCntrl1 = new subUserCntrl();

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            subUserCntrl1.MyCusEvent += new EventHandler(subUserCntrl1_MyCusEvent);
        }

        void subUserCntrl1_MyCusEvent(object sender, EventArgs e)
        {
            MessageBox.Show("Test");
        }
    }

    public partial class SubUserCntrl : UserControl
    {
        public event EventHandler MyCusEvent;

        public SubUserCntrl()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (MyCusEvent != null)
                MyCusEvent(this, e);        
        }
    }
I dropped on from my ToolBox onto my form...

But it would work the same with a dynamic control.  Just give it a location and add it to the controls collection:

        subUserCntrl subUserCntrl1 = new subUserCntrl();

        private void Form1_Load(object sender, EventArgs e)
        {
            subUserCntrl1.Location = new Point(25, 25);
            this.Controls.Add(subUserCntrl1);
            subUserCntrl1.MyCusEvent += new EventHandler(subUserCntrl1_MyCusEvent);
        }
Avatar of San24

ASKER

Not related to the topic...What is a better programming practice .. To put the initialization statements in Form1() or Form1_Load(object sender, EventArgs e)
Depends on what your initializing...  ;)

In the constructor your form doesn't have a handle yet so you can't base things off of the size of anything...the Load() event would be necessary then.

Other than that it doesn't matter too much for most things.
Avatar of San24

ASKER

Okay I`m a bit confused now.

I already have an instance of the User Control loaded like this .. dynamically.  
My first tep is to load all the User Controls through MenuItems events. So would I just add it to the Controls collection in this step?


 private void NewFileSitch(ToolStripItemClickedEventArgs e)
        {

            switch(e.ClickedItem.ToString())
            {
                case "ParamOne":

                    TabsUserCntrl TUC_H = new TabsUserCntrl();
                    subUserCntrl HX = new subUserCntrl();
                    HX.Name = "XYZ";
                    TabPage TP_H = new TabPage();
                    TP_H.Text = "Param One";
                    TP_H.BackColor = Color.White;

                    TabCount();

                    TUC_H.panel1.Controls.Add(HX);  
                    //TUC_H.WindTab.Controls.Add(HX);
                    TP_H.Controls.Add(TUC_H);
                    MainTabCntrl.TabPages.Add(TP_H);  

                    break;

                case "ParamTwo":
                    TabsUserCntrl TUC_C = new TabsUserCntrl();
                    abcUserCntrl CX = new abcUserCntrl();
                    TabPage TP_C = new TabPage();
                    TP_C.Text = "Param Two";
                    TP_C.BackColor = Color.White;

                    TabCount();

                    TUC_C.panel1.Controls.Add(CX);    
                    TP_C.Controls.Add(TUC_C);
                    MainTabCntrl.TabPages.Add(TP_C);  
                    break;

                default:
                    break;
            }
        }
It looks like it's being added properly.  =)

Where are you wiring up the event then?  You need to wire up the event for that actual instance that you created...
Avatar of San24

ASKER

So I`m creating an instance here -

case "ParamOne":

                    TabsUserCntrl TUC_H = new TabsUserCntrl();
                    subUserCntrl HX = new subUserCntrl();
                    HX.Name = "XYZ";
                    TabPage TP_H = new TabPage();
                    TP_H.Text = "Param One";
                    TP_H.BackColor = Color.White;

                    TabCount();

Would I be wiring the event here?

something like this?

case "ParamOne":

                    TabsUserCntrl TUC_H = new TabsUserCntrl();
                    subUserCntrl HX = new subUserCntrl();
                    HX.Name = "XYZ";
                    TabPage TP_H = new TabPage();
                    TP_H.Text = "Param One";
                    TP_H.BackColor = Color.White;
                    //Added this
                    HX.MyCusEvent += new EventHandler(HX_MyCusEvent);

                    TabCount();


and then do this -

private void HX_MyCusEvent(object sender, EventArgs e)
        {
         //Do Something here
            MessageBox.Show("Test");  
        }


I`m I getting this completely wrong? Can you give me an example?
Yes...that should be right...but I'm guessing you're going to say that it doesn't work?  =\

If so, I think I'd either need to see more code or possibly play with a test project to figure out where the problem is...
Avatar of San24

ASKER

Haha...actually it works fine! I just need to understand the process - a semi newbie here. Right now I`m just doing trial and error - not the most efficient way. Let me play with this more and then close this thread. Thanks for your patience and help.

Now, I`ve figured out bubbling events from the User Control to the Main UI. Now I need to work on reversing it. I`ll keep you updated.

Isn`t Bubbling nothing but Publishing and Subscribing events? Or is that completely different.
Yes...bubbling is just subscribing to raised events.  The actual "bubbling", though, occurs when the event is raised from a control that is nested more than one level deep and it has to be captured and then rebroadcast at an intermediate level before it reaches the main level.