First, I assume you have a good reason for wanting to make your Form, 'cem, have an "Owner."
That you want 'cem to be shown/hidden/closed when the main Form is shown/hidden/closed.
And, that you want 'cem to always appear above the main Form visually. Those two "behaviors" are what the use of the 'Owner property
enables: very useful for things like find-and-replace dialogues, and other UI elements you want to be
persistent, but, unlike using 'ShowDialog,
do not block using the rest of your Application.
In a nutshell: you want an Event ... a Click Event ... of a Button in 'cem to have an effect on a ComboBox in ... what we assume is ... your main Form of Type 'Form1. And, this effect will happen
only when a certain RadioButton is "checked."
The road-block you've run into is the fact that:
even if you have a valid reference to the Owner of a Form at run-time, you cannot access its
private members using that reference.
There are
many ways you can go about enabling "communication" between Forms. The general principle (separation of concerns, loose-coupling) that is best to follow is to create the minimum "dependency"
between your Application's Objects, to expose to one Object only what it needs to have, or needs to know, to perform specific tasks that require it to have access to some other Object.
Now it is logical, in this case, to claim that there
is a hard-coded dependency between your Main Form and the Form 'cem: setting 'cem's 'Owner property creates that behavioral dependency.
On a practical level, what all this means is that we want to be "stingy" with information: we want the Main Form to know only that
something happened that requires a change in one of its UI elements; we want the 'cem Form to know "nothing" about "who created it," even though it does have this special relationship with the Main Form via the 'Owner property.
Okay, to bring all this "down to earth," let's get coding:
1. define a private Method with no parameters that does not return a value in the Main Form
private void SetComboBox4()
{
comboBox4.Text = "First";
}
2. in the 'cem Form definition create a Public property of type 'Action:
public Action TheAction { set; get; }
3. When the Main Form creates an instance of the 'Ce Form, we inject a reference to the 'SetComboBox4 method into the property of type 'Action defined in 'cem:"
public Form1()
{
InitializeComponent();
cem = new Ce();
cem.TopLevel = true;
cem.StartPosition = FormStartPosition.CenterScreen;
cem.Owner = this;
cem.TheAction = SetComboBox4;
}
Ce cem;
4. now, in the Button ClickEventHandler in Form 'cem:
private void button1_Click(object sender, EventArgs e)
{
if (radioButton1.Checked)
{
TheAction();
}
this.Hide();
}
We execute the method defined in the Main Form that we have "injected" into 'cem.
If you are new to the concepts of using the 'Action and 'Func forms of Delegates which came into .NET with FrameWork version 3.5 (the first form of Action<T> appeared in .NET 2.0), I encourage you to study: [
^], [
^], [
^].
An investment in learning to use 'Action, and 'Func delegates is well worth your time because: they are very powerful tools used in combination with Linq.
Technically speaking, when we injected the reference to a method into an instance of 'cem: we passed a
pointer to the method 'SetComboBox4.
Here's the end result:
Main Form:
using System;
using System.Windows.Forms;
namespace TestTwoForms
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
cem = new Ce();
cem.TopLevel = true;
cem.StartPosition = FormStartPosition.CenterScreen;
cem.Owner = this;
cem.TheAction = SetComboBox4;
}
Ce cem;
private void button2_Click(object sender, EventArgs e)
{
if (! cem.Visible) cem.Visible = true;
}
private void SetComboBox4()
{
comboBox4.Text = "First";
}
}
}
Form 'cem:
using System;
using System.Windows.Forms;
namespace TestTwoForms
{
public partial class Ce : Form
{
public Ce()
{
InitializeComponent();
}
public Action TheAction { set; get; }
private void button1_Click(object sender, EventArgs e)
{
if (radioButton1.Checked) TheAction();
this.Hide();
}
}
}