Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C++/CLI

Passing Data Between Forms Using Events & Delegates (C++/CLI)

3.91/5 (5 votes)
18 Jan 2017CPOL2 min read 28.3K   668  
A Visual Studio 2015 project that shows one way to pass information between Windows Forms

Introduction

This simple project contains a main (parent) form and 2 child forms.

The main form passes a string to each child form.

Each child form passes a string to the main form and also to the other child form.

It's not obvious to me how to pass a string directly from 1 child form to the other child form (yet). So my solution has each child form passing a string to the main form, which in turn relays the string to the other child form.

I welcome any solution you might have that doesn't involve this relay mechanism.

Background

I've programmed for many years but never saw the need to pass data between forms, other than passing objects by reference.

When I heard about delegates, I searched for simple examples but most were mired in extraneous code.

Hopefully, my example will help you understand the basics.

Using the Code

The main form includes a reference to each child form:

C++
#include "ChildForm1.h"
#include "ChildForm2.h"
C++
private: ChildForm1^ c1;
private: ChildForm2^ c2;

In the load method of the main form, an object of each child form is created:

C++
this->c1 = gcnew ChildForm1();
this->c2 = gcnew ChildForm2();

The following shows how a string is sent directly from the main form to each child form - nothing magic here - no delegates required.

The SetTextBox method in each child form must be declared as public:

C++
private: System::Void sendButton1(System::Object^  sender, System::EventArgs^  e) 
{
	this->c1->SetTextBox1(this->textBox3->Text);
}
private: System::Void sendButton2(System::Object^  sender, System::EventArgs^  e) 
{
	this->c2->SetTextBox1(this->textBox4->Text);
}

Next, the main form subscribes (as a listener) to the child form "send text" published events:

The "+=" means that we're subscribing. At any time, you can unsubscribe by using "-=".

Notice how the 2nd argument below has to be a complete specification for the main form's event handlers. Don't forget the '&' before the namespace (& + namespace + subscriber's form name + subscriber's event handler).

I use 4 listeners - 2 for a string from each child form to the parent form & 2 for a string from each child form that gets relayed to the other child form.

C++
// Events have only 2 args
this->c1->myEvent1 += gcnew ChildForm1::EventDelegate1
(this, &PassingDataBetweenForms::Form1::mySubscriber1a);
this->c1->myEvent2 += gcnew ChildForm1::EventDelegate2
(this, &PassingDataBetweenForms::Form1::mySubscriber1b);
this->c2->myEvent1 += gcnew ChildForm2::EventDelegate1
(this, &PassingDataBetweenForms::Form1::mySubscriber2a);
this->c2->myEvent2 += gcnew ChildForm2::EventDelegate2
(this, &PassingDataBetweenForms::Form1::mySubscriber2b);

Here are the main form's subscriber event handlers which were declared above. When a child publishes an event, a string is displayed in the target form's TextBox:

C++
private: void mySubscriber1a
(System::Object^  sender, System::EventArgs^  e, String^ text) // From child form 1
{
	this->textBox1->Text = text; // Here's where we display the message from child1 to parent
}
private: void mySubscriber1b
(System::Object^  sender, System::EventArgs^  e, String^ text) // From child form 1
{
	this->c2->SetTextBox2(text); // Here's where we forward the message from child2 to child1
}
private: void mySubscriber2a
(System::Object^  sender, System::EventArgs^  e, String^ text) // From child form 2
{
	this->textBox2->Text = text; // Here's where we display the message from child2 to  parent 
}
private: void mySubscriber2b
(System::Object^  sender, System::EventArgs^  e, String^ text) // From child form 2
{
	this->c1->SetTextBox2(text); // Here's where we forward the message from child1 to child2
}

The child forms have the responsibility to define (public) delegates & events in order to publish strings for the subscriber (main form) to listen for.

In this case, one event sends a string to its parent and the other sends a string to its sibling (via the parent).

C++
// Publish an event (with a text message) that other forms can subscribe to
public: delegate void EventDelegate1(System::Object^ sender, System::EventArgs^ e, String^ message);
public: event EventDelegate1^ myEvent1;
public: delegate void EventDelegate2(System::Object^ sender, System::EventArgs^ e, String^ message);
public: event EventDelegate2^ myEvent2;

Notice that there is no #include in either child form (referencing the other child form) because that would create a circular reference, which would not compile.

So when a child's send button is clicked, it triggers one of its event handlers:

C++
public: void issueEvent1(System::Object^  sender, System::EventArgs^  e)	//This is where 
                                                               //we publish the event to all subscribers
{
	this->myEvent1(this, e, this->textBox3->Text); // Raise the event using the EventDelegate signature
}
public: void issueEvent2(System::Object^  sender, System::EventArgs^  e)	//This is where 
                                                               //we publish the event to all subscribers
{
	this->myEvent2(this, e, this->textBox4->Text); // Raise the event using the EventDelegate signature
}

Notice that here is where we add the strings (to be published) as the 3rd argument, per the EventDelegate declaration above.

I hope this simple example will help demystify events, delegates, publishers and subscribers, as it did for me.

The Main Form

C++
#pragma once

#include "Child Form 1.h"
#include "Child Form 2.h"

namespace PassingDataBetweenForms {

    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Collections::Generic;
    using namespace System::Windows::Forms;
    using namespace System::Drawing;
    using namespace System::Text;
    using namespace System::Diagnostics;

    public ref class Form1 : public System::Windows::Forms::Form
    {
    public:
        Form1(void)
        {
            InitializeComponent();
            //
            //TODO: Add the constructor code here
            //
        }

    protected:
        ~Form1()
        {
            if (components)
            {
                delete components;
            }
        }
    private: System::Windows::Forms::Button^  button1;
    private: System::Windows::Forms::Button^  button2;
    private: System::Windows::Forms::TextBox^  textBox1;
    private: System::Windows::Forms::TextBox^  textBox2;
    private: System::Windows::Forms::Label^  label1;
    private: System::Windows::Forms::Label^  label2;
    private: System::Windows::Forms::Label^  label3;
    private: System::Windows::Forms::Label^  label4;
    private: System::Windows::Forms::TextBox^  textBox4;
    private: System::Windows::Forms::TextBox^  textBox3;

    private:
        System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        void InitializeComponent(void)
        {
            this->button1 = (gcnew System::Windows::Forms::Button());
            this->button2 = (gcnew System::Windows::Forms::Button());
            this->textBox1 = (gcnew System::Windows::Forms::TextBox());
            this->textBox2 = (gcnew System::Windows::Forms::TextBox());
            this->label1 = (gcnew System::Windows::Forms::Label());
            this->label2 = (gcnew System::Windows::Forms::Label());
            this->label3 = (gcnew System::Windows::Forms::Label());
            this->label4 = (gcnew System::Windows::Forms::Label());
            this->textBox4 = (gcnew System::Windows::Forms::TextBox());
            this->textBox3 = (gcnew System::Windows::Forms::TextBox());
            this->SuspendLayout();
            // 
            // button1
            // 
            this->button1->Location = System::Drawing::Point(30, 238);
            this->button1->Name = L"button1";
            this->button1->Size = System::Drawing::Size(127, 27);
            this->button1->TabIndex = 0;
            this->button1->Text = L"Send";
            this->button1->UseVisualStyleBackColor = true;
            this->button1->Click += gcnew System::EventHandler(this, &Form1::sendButton1);
            // 
            // button2
            // 
            this->button2->Location = System::Drawing::Point(173, 238);
            this->button2->Name = L"button2";
            this->button2->Size = System::Drawing::Size(127, 27);
            this->button2->TabIndex = 1;
            this->button2->Text = L"Send";
            this->button2->UseVisualStyleBackColor = true;
            this->button2->Click += gcnew System::EventHandler(this, &Form1::sendButton2);
            // 
            // textBox1
            // 
            this->textBox1->Location = System::Drawing::Point(30, 37);
            this->textBox1->Multiline = true;
            this->textBox1->Name = L"textBox1";
            this->textBox1->Size = System::Drawing::Size(127, 79);
            this->textBox1->TabIndex = 2;
            // 
            // textBox2
            // 
            this->textBox2->Location = System::Drawing::Point(173, 37);
            this->textBox2->Multiline = true;
            this->textBox2->Name = L"textBox2";
            this->textBox2->Size = System::Drawing::Size(127, 79);
            this->textBox2->TabIndex = 3;
            // 
            // label1
            // 
            this->label1->AutoSize = true;
            this->label1->Location = System::Drawing::Point(40, 13);
            this->label1->Name = L"label1";
            this->label1->Size = System::Drawing::Size(106, 17);
            this->label1->TabIndex = 4;
            this->label1->Text = L"Data From Child 1";
            // 
            // label2
            // 
            this->label2->AutoSize = true;
            this->label2->Location = System::Drawing::Point(182, 13);
            this->label2->Name = L"label2";
            this->label2->Size = System::Drawing::Size(108, 17);
            this->label2->TabIndex = 5;
            this->label2->Text = L"Data From Child 2";
            // 
            // label3
            // 
            this->label3->AutoSize = true;
            this->label3->Location = System::Drawing::Point(189, 121);
            this->label3->Name = L"label3";
            this->label3->Size = System::Drawing::Size(95, 17);
            this->label3->TabIndex = 19;
            this->label3->Text = L"Data To Child 2";
            // 
            // label4
            // 
            this->label4->AutoSize = true;
            this->label4->Location = System::Drawing::Point(47, 121);
            this->label4->Name = L"label4";
            this->label4->Size = System::Drawing::Size(93, 17);
            this->label4->TabIndex = 18;
            this->label4->Text = L"Data To Child 1";
            // 
            // textBox4
            // 
            this->textBox4->Location = System::Drawing::Point(173, 145);
            this->textBox4->Multiline = true;
            this->textBox4->Name = L"textBox4";
            this->textBox4->Size = System::Drawing::Size(127, 79);
            this->textBox4->TabIndex = 17;
            // 
            // textBox3
            // 
            this->textBox3->Location = System::Drawing::Point(30, 145);
            this->textBox3->Multiline = true;
            this->textBox3->Name = L"textBox3";
            this->textBox3->Size = System::Drawing::Size(127, 79);
            this->textBox3->TabIndex = 16;
            // 
            // Form1
            // 
            this->AutoScaleDimensions = System::Drawing::SizeF(7, 17);
            this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
            this->BackColor = System::Drawing::Color::FromArgb
                (static_cast<System::Int32>(static_cast<System::Byte>(182)), 
                static_cast<System::Int32>(static_cast<System::Byte>(200)), 
                static_cast<System::Int32>(static_cast<System::Byte>(200)));
            this->ClientSize = System::Drawing::Size(331, 287);
            this->Controls->Add(this->label3);
            this->Controls->Add(this->label4);
            this->Controls->Add(this->textBox4);
            this->Controls->Add(this->textBox3);
            this->Controls->Add(this->label2);
            this->Controls->Add(this->label1);
            this->Controls->Add(this->textBox2);
            this->Controls->Add(this->textBox1);
            this->Controls->Add(this->button2);
            this->Controls->Add(this->button1);
            this->Font = (gcnew System::Drawing::Font(L"Comic Sans MS", 9, 
                         System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, 
                static_cast<System::Byte>(0)));
            this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedSingle;
            this->Margin = System::Windows::Forms::Padding(3, 4, 3, 4);
            this->MaximizeBox = false;
            this->MinimizeBox = false;
            this->Name = L"Form1";
            this->Text = L"Parent Form";
            this->Load += gcnew System::EventHandler(this, &Form1::load);
            this->Shown += gcnew System::EventHandler(this, &Form1::shown);
            this->ResumeLayout(false);
            this->PerformLayout();
        }
#pragma endregion
    private: ChildForm1^ c1;
    private: ChildForm2^ c2;

    private: System::Void load(System::Object^  sender, System::EventArgs^  e) {
        this->textBox3->Text = "hi child1 from parent";
        this->textBox4->Text = "hi child2 from parent";

        this->c1 = gcnew ChildForm1();
        this->c2 = gcnew ChildForm2();

        // The main form subscribes (as a listener) to the child form "send text" 
        // published events - these are the declarations for the event handlers shown below
        this->c1->myEvent1 += gcnew ChildForm1::EventDelegate1
         (this, &PassingDataBetweenForms::Form1::mySubscriber1a); // Events have only 2 args
        this->c1->myEvent2 += gcnew ChildForm1::EventDelegate2
         (this, &PassingDataBetweenForms::Form1::mySubscriber1b); // Events have only 2 args
        this->c2->myEvent1 += gcnew ChildForm2::EventDelegate1
         (this, &PassingDataBetweenForms::Form1::mySubscriber2a); // Events have only 2 args
        this->c2->myEvent2 += gcnew ChildForm2::EventDelegate2
         (this, &PassingDataBetweenForms::Form1::mySubscriber2b); // Events have only 2 args
    }
    private: System::Void shown(System::Object^  sender, System::EventArgs^  e) {
        this->c1->Show();
        this->c2->Show();
    }

    // The main form's subscriber event handlers which are declared above
    private: void mySubscriber1a(System::Object^  sender, 
          System::EventArgs^  e, String^ text) // From child form 1
    {
        this->textBox1->Text = text; // Here's where we display the message from the child1
    }
    private: void mySubscriber1b(System::Object^  sender, 
          System::EventArgs^  e, String^ text) // From child form 1
    {
        this->c2->SetTextBox2(text);  // Here's where we forward the message from child2 to child1
    }
    private: void mySubscriber2a(System::Object^  sender, 
         System::EventArgs^  e, String^ text) // From child form 2
    {
        this->textBox2->Text = text; // Here's where we display the message from the child2
    }
    private: void mySubscriber2b(System::Object^  sender, 
         System::EventArgs^  e, String^ text) // From child form 2
    {
        this->c1->SetTextBox2(text); // Here's where we forward the message from child1 to child2
    }

    private: System::Void sendButton1(System::Object^  sender, System::EventArgs^  e) {
        this->c1->SetTextBox1(this->textBox3->Text);
    }
    private: System::Void sendButton2(System::Object^  sender, System::EventArgs^  e) {
        this->c2->SetTextBox1(this->textBox4->Text);
    }
};
}

Child Form 1

C++
#pragma once

namespace PassingDataBetweenForms {

    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Collections::Generic;
    using namespace System::Windows::Forms;
    using namespace System::Drawing;
    using namespace System::Text;
    using namespace System::Diagnostics;

    public ref class ChildForm1 : public System::Windows::Forms::Form
    {
    // Public events (using delegates) are declared here in order to publish strings 
    // for the subscriber (main form) who listens to these events
    public: delegate void EventDelegate1(System::Object^ sender, 
          System::EventArgs^ e, String^ message); // Publish an event (with a text message) 
                                                  // that others can subscribe to
    public: event EventDelegate1^ myEvent1;
    public: delegate void EventDelegate2(System::Object^ sender, 
             System::EventArgs^ e, String^ message); // Publish an event (with a text message) 
                                                     // that others can subscribe to
    public: event EventDelegate2^ myEvent2;

    public:
        ChildForm1(void)
        {
            InitializeComponent();
            //
            //TODO: Add the constructor code here
            //
        }

    protected:
        ~ChildForm1()
        {
            if (components)
            {
                delete components;
            }
        }
    private: System::Windows::Forms::Label^  label3;
    private: System::Windows::Forms::Label^  label4;
    private: System::Windows::Forms::TextBox^  textBox4;
    private: System::Windows::Forms::TextBox^  textBox3;
    private: System::Windows::Forms::Label^  label2;
    private: System::Windows::Forms::Label^  label1;
    private: System::Windows::Forms::TextBox^  textBox2;
    private: System::Windows::Forms::TextBox^  textBox1;
    private: System::Windows::Forms::Button^  button2;
    private: System::Windows::Forms::Button^  button1;

    private:
        System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        void InitializeComponent(void)
        {
            this->label3 = (gcnew System::Windows::Forms::Label());
            this->label4 = (gcnew System::Windows::Forms::Label());
            this->textBox4 = (gcnew System::Windows::Forms::TextBox());
            this->textBox3 = (gcnew System::Windows::Forms::TextBox());
            this->label2 = (gcnew System::Windows::Forms::Label());
            this->label1 = (gcnew System::Windows::Forms::Label());
            this->textBox2 = (gcnew System::Windows::Forms::TextBox());
            this->textBox1 = (gcnew System::Windows::Forms::TextBox());
            this->button2 = (gcnew System::Windows::Forms::Button());
            this->button1 = (gcnew System::Windows::Forms::Button());
            this->SuspendLayout();
            // 
            // label3
            // 
            this->label3->AutoSize = true;
            this->label3->Location = System::Drawing::Point(189, 121);
            this->label3->Name = L"label3";
            this->label3->Size = System::Drawing::Size(95, 17);
            this->label3->TabIndex = 29;
            this->label3->Text = L"Data To Sibling";
            // 
            // label4
            // 
            this->label4->AutoSize = true;
            this->label4->Location = System::Drawing::Point(47, 121);
            this->label4->Name = L"label4";
            this->label4->Size = System::Drawing::Size(93, 17);
            this->label4->TabIndex = 28;
            this->label4->Text = L"Data To Parent";
            // 
            // textBox4
            // 
            this->textBox4->Location = System::Drawing::Point(173, 145);
            this->textBox4->Multiline = true;
            this->textBox4->Name = L"textBox4";
            this->textBox4->Size = System::Drawing::Size(127, 79);
            this->textBox4->TabIndex = 27;
            // 
            // textBox3
            // 
            this->textBox3->Location = System::Drawing::Point(30, 145);
            this->textBox3->Multiline = true;
            this->textBox3->Name = L"textBox3";
            this->textBox3->Size = System::Drawing::Size(127, 79);
            this->textBox3->TabIndex = 26;
            // 
            // label2
            // 
            this->label2->AutoSize = true;
            this->label2->Location = System::Drawing::Point(182, 13);
            this->label2->Name = L"label2";
            this->label2->Size = System::Drawing::Size(108, 17);
            this->label2->TabIndex = 25;
            this->label2->Text = L"Data From Sibling";
            // 
            // label1
            // 
            this->label1->AutoSize = true;
            this->label1->Location = System::Drawing::Point(40, 13);
            this->label1->Name = L"label1";
            this->label1->Size = System::Drawing::Size(106, 17);
            this->label1->TabIndex = 24;
            this->label1->Text = L"Data From Parent";
            // 
            // textBox2
            // 
            this->textBox2->Location = System::Drawing::Point(173, 37);
            this->textBox2->Multiline = true;
            this->textBox2->Name = L"textBox2";
            this->textBox2->Size = System::Drawing::Size(127, 79);
            this->textBox2->TabIndex = 23;
            // 
            // textBox1
            // 
            this->textBox1->Location = System::Drawing::Point(30, 37);
            this->textBox1->Multiline = true;
            this->textBox1->Name = L"textBox1";
            this->textBox1->Size = System::Drawing::Size(127, 79);
            this->textBox1->TabIndex = 22;
            // 
            // button2
            // 
            this->button2->Location = System::Drawing::Point(173, 238);
            this->button2->Name = L"button2";
            this->button2->Size = System::Drawing::Size(127, 27);
            this->button2->TabIndex = 21;
            this->button2->Text = L"Send";
            this->button2->UseVisualStyleBackColor = true;
            this->button2->Click += gcnew System::EventHandler(this, &ChildForm1::sendButton2);
            // 
            // button1
            // 
            this->button1->Location = System::Drawing::Point(30, 238);
            this->button1->Name = L"button1";
            this->button1->Size = System::Drawing::Size(127, 27);
            this->button1->TabIndex = 20;
            this->button1->Text = L"Send";
            this->button1->UseVisualStyleBackColor = true;
            this->button1->Click += gcnew System::EventHandler(this, &ChildForm1::sendButton1);
            // 
            // ChildForm1
            // 
            this->AutoScaleDimensions = System::Drawing::SizeF(7, 17);
            this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
            this->BackColor = System::Drawing::Color::FromArgb
                              (static_cast<System::Int32>(static_cast<System::Byte>(182)), 
                              static_cast<System::Int32>(static_cast<System::Byte>(200)), 
                static_cast<System::Int32>(static_cast<System::Byte>(200)));
            this->ClientSize = System::Drawing::Size(331, 287);
            this->Controls->Add(this->label3);
            this->Controls->Add(this->label4);
            this->Controls->Add(this->textBox4);
            this->Controls->Add(this->textBox3);
            this->Controls->Add(this->label2);
            this->Controls->Add(this->label1);
            this->Controls->Add(this->textBox2);
            this->Controls->Add(this->textBox1);
            this->Controls->Add(this->button2);
            this->Controls->Add(this->button1);
            this->Font = (gcnew System::Drawing::Font(L"Comic Sans MS", 9));
            this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedSingle;
            this->Margin = System::Windows::Forms::Padding(3, 4, 3, 4);
            this->Name = L"ChildForm1";
            this->Text = L"ChildForm1";
            this->Load += gcnew System::EventHandler(this, &ChildForm1::load);
            this->ResumeLayout(false);
            this->PerformLayout();

        }
#pragma endregion
    // My problem is how a child form can subscribe to another sibling's event - 
    // you need to construct an instance of the sibling & I don't know how to do that
    // So my current solution is to have the each child send a message to the parent, 
    // who in turn relays the message to its sibling.
    private: System::Void load(System::Object^  sender, System::EventArgs^  e)
    {
        this->textBox3->Text = "hi parent from child1";
        this->textBox4->Text = "hi child2 from child1";
    }
    
    public: void issueEvent1(System::Object^  sender, System::EventArgs^  e)    //This is where 
                                                          //we publish the event to all subscribers
    {
        this->myEvent1(this, e, this->textBox3->Text); // Raise the event using the EventDelegate 
                                                       // signature
    }
    public: void issueEvent2(System::Object^  sender, System::EventArgs^  e)    //This is where we 
                                                              //publish the event to all subscribers
    {
        this->myEvent2(this, e, this->textBox4->Text); // Raise the event using the 
                                                       // EventDelegate signature
    }
    
    public: void SetTextBox1(String^ string)
    {
        this->textBox1->Text = string;
    }
    public: void SetTextBox2(String^ string)
    {
        this->textBox2->Text = string;
    }
    
    private: System::Void sendButton1(System::Object^  sender, System::EventArgs^  e) {
        this->issueEvent1(sender, e);
    }
    private: System::Void sendButton2(System::Object^  sender, System::EventArgs^  e) {
        this->issueEvent2(sender, e);
    }
};
}

Child Form 2

C++
#pragma once

namespace PassingDataBetweenForms {

    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Collections::Generic;
    using namespace System::Windows::Forms;
    using namespace System::Drawing;
    using namespace System::Text;
    using namespace System::Diagnostics;

    public ref class ChildForm2 : public System::Windows::Forms::Form
    {
    // Public events (using delegates) are declared here in order to publish strings 
    // for the subscriber (main form) who listens to these events
    public: delegate void EventDelegate1(System::Object^ sender, System::EventArgs^ e, 
      String^ message); // Publish an event (with a text message) that others can subscribe to
    public: event EventDelegate1^ myEvent1;
    public: delegate void EventDelegate2(System::Object^ sender, System::EventArgs^ e, 
      String^ message); // Publish an event (with a text message) that others can subscribe to
    public: event EventDelegate2^ myEvent2;

    public:
        ChildForm2(void)
        {
            InitializeComponent();
            //
            //TODO: Add the constructor code here
            //
        }

    protected:
        ~ChildForm2()
        {
            if (components)
            {
                delete components;
            }
        }
    private: System::Windows::Forms::Label^  label3;
    private: System::Windows::Forms::Label^  label4;
    private: System::Windows::Forms::TextBox^  textBox4;
    private: System::Windows::Forms::TextBox^  textBox3;
    private: System::Windows::Forms::Label^  label2;
    private: System::Windows::Forms::Label^  label1;
    private: System::Windows::Forms::TextBox^  textBox2;
    private: System::Windows::Forms::TextBox^  textBox1;
    private: System::Windows::Forms::Button^  button2;
    private: System::Windows::Forms::Button^  button1;

    private:
        System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        void InitializeComponent(void)
        {
            this->label3 = (gcnew System::Windows::Forms::Label());
            this->label4 = (gcnew System::Windows::Forms::Label());
            this->textBox4 = (gcnew System::Windows::Forms::TextBox());
            this->textBox3 = (gcnew System::Windows::Forms::TextBox());
            this->label2 = (gcnew System::Windows::Forms::Label());
            this->label1 = (gcnew System::Windows::Forms::Label());
            this->textBox2 = (gcnew System::Windows::Forms::TextBox());
            this->textBox1 = (gcnew System::Windows::Forms::TextBox());
            this->button2 = (gcnew System::Windows::Forms::Button());
            this->button1 = (gcnew System::Windows::Forms::Button());
            this->SuspendLayout();
            // 
            // label3
            // 
            this->label3->AutoSize = true;
            this->label3->Location = System::Drawing::Point(189, 121);
            this->label3->Name = L"label3";
            this->label3->Size = System::Drawing::Size(95, 17);
            this->label3->TabIndex = 29;
            this->label3->Text = L"Data To Sibling";
            // 
            // label4
            // 
            this->label4->AutoSize = true;
            this->label4->Location = System::Drawing::Point(47, 121);
            this->label4->Name = L"label4";
            this->label4->Size = System::Drawing::Size(93, 17);
            this->label4->TabIndex = 28;
            this->label4->Text = L"Data To Parent";
            // 
            // textBox4
            // 
            this->textBox4->Location = System::Drawing::Point(173, 145);
            this->textBox4->Multiline = true;
            this->textBox4->Name = L"textBox4";
            this->textBox4->Size = System::Drawing::Size(127, 79);
            this->textBox4->TabIndex = 27;
            // 
            // textBox3
            // 
            this->textBox3->Location = System::Drawing::Point(30, 145);
            this->textBox3->Multiline = true;
            this->textBox3->Name = L"textBox3";
            this->textBox3->Size = System::Drawing::Size(127, 79);
            this->textBox3->TabIndex = 26;
            // 
            // label2
            // 
            this->label2->AutoSize = true;
            this->label2->Location = System::Drawing::Point(182, 13);
            this->label2->Name = L"label2";
            this->label2->Size = System::Drawing::Size(108, 17);
            this->label2->TabIndex = 25;
            this->label2->Text = L"Data From Sibling";
            // 
            // label1
            // 
            this->label1->AutoSize = true;
            this->label1->Location = System::Drawing::Point(40, 13);
            this->label1->Name = L"label1";
            this->label1->Size = System::Drawing::Size(106, 17);
            this->label1->TabIndex = 24;
            this->label1->Text = L"Data From Parent";
            // 
            // textBox2
            // 
            this->textBox2->Location = System::Drawing::Point(173, 37);
            this->textBox2->Multiline = true;
            this->textBox2->Name = L"textBox2";
            this->textBox2->Size = System::Drawing::Size(127, 79);
            this->textBox2->TabIndex = 23;
            // 
            // textBox1
            // 
            this->textBox1->Location = System::Drawing::Point(30, 37);
            this->textBox1->Multiline = true;
            this->textBox1->Name = L"textBox1";
            this->textBox1->Size = System::Drawing::Size(127, 79);
            this->textBox1->TabIndex = 22;
            // 
            // button2
            // 
            this->button2->Location = System::Drawing::Point(173, 238);
            this->button2->Name = L"button2";
            this->button2->Size = System::Drawing::Size(127, 27);
            this->button2->TabIndex = 21;
            this->button2->Text = L"Send";
            this->button2->UseVisualStyleBackColor = true;
            this->button2->Click += gcnew System::EventHandler(this, &ChildForm2::sendButton2);
            // 
            // button1
            // 
            this->button1->Location = System::Drawing::Point(30, 238);
            this->button1->Name = L"button1";
            this->button1->Size = System::Drawing::Size(127, 27);
            this->button1->TabIndex = 20;
            this->button1->Text = L"Send";
            this->button1->UseVisualStyleBackColor = true;
            this->button1->Click += gcnew System::EventHandler(this, &ChildForm2::sendButton1);
            // 
            // ChildForm2
            // 
            this->AutoScaleDimensions = System::Drawing::SizeF(7, 17);
            this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
            this->BackColor = System::Drawing::Color::FromArgb
                   (static_cast<System::Int32>(static_cast<System::Byte>(182)), 
                    static_cast<System::Int32>(static_cast<System::Byte>(200)), 
                static_cast<System::Int32>(static_cast<System::Byte>(200)));
            this->ClientSize = System::Drawing::Size(331, 287);
            this->Controls->Add(this->label3);
            this->Controls->Add(this->label4);
            this->Controls->Add(this->textBox4);
            this->Controls->Add(this->textBox3);
            this->Controls->Add(this->label2);
            this->Controls->Add(this->label1);
            this->Controls->Add(this->textBox2);
            this->Controls->Add(this->textBox1);
            this->Controls->Add(this->button2);
            this->Controls->Add(this->button1);
            this->Font = (gcnew System::Drawing::Font(L"Comic Sans MS", 9));
            this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedSingle;
            this->Margin = System::Windows::Forms::Padding(3, 4, 3, 4);
            this->Name = L"ChildForm2";
            this->Text = L"ChildForm2";
            this->Load += gcnew System::EventHandler(this, &ChildForm2::load);
            this->ResumeLayout(false);
            this->PerformLayout();

        }
#pragma endregion
    // My problem is how a child form can subscribe to another sibling's event - you need to 
    // construct an instance of the sibling & I don't know how to do that
    // So my current solution is to have the each child send a message to the parent, 
    // who in turn relays the message to its sibling.
    private: System::Void load(System::Object^  sender, System::EventArgs^  e)
    {
        this->textBox3->Text = "hi parent from child2";
        this->textBox4->Text = "hi child1 from child2";
    }

    public: void issueEvent1(System::Object^  sender, System::EventArgs^  e)    //This is where we 
                                                            //publish the event to all subscribers
    {
        this->myEvent1(this, e, this->textBox3->Text); // Raise the event using the EventDelegate 
                                                       // signature
    }
    public: void issueEvent2(System::Object^  sender, System::EventArgs^  e)    //This is where we 
                                                            //publish the event to all subscribers
    {
        this->myEvent2(this, e, this->textBox4->Text); // Raise the event using the EventDelegate 
                                                       // signature
    }

    public: void SetTextBox1(String^ string)
    {
        this->textBox1->Text = string;
    }
    public: void SetTextBox2(String^ string)
    {
        this->textBox2->Text = string;
    }

    private: System::Void sendButton1(System::Object^  sender, System::EventArgs^  e) {
        this->issueEvent1(sender, e);
    }
    private: System::Void sendButton2(System::Object^  sender, System::EventArgs^  e) {
        this->issueEvent2(sender, e);
    }
};
}

License

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