wulfgarpro
wulfgarpro

Reputation: 6924

How to access a form control for another form?

I have two Form classes, one of which has a ListBox. I need a setter for the SelectedIndex property of the ListBox, which I want to call from the second Form.

At the moment I am doing the following:

Form 1

public int MyListBoxSelectedIndex
{
     set { lsbMyList.SelectedIndex = value; }
}

Form 2

private ControlForm mainForm; // form 1

public AddNewObjForm()
{
     InitializeComponent();
     mainForm = new ControlForm();           
}

public void SomeMethod()
{
     mainForm.MyListBoxSelectedIndex = -1;
}

Is this the best way to do this?

Upvotes: 16

Views: 133815

Answers (7)

aderchox
aderchox

Reputation: 4074

Here's also another example that does "Find and Highlight". There's a second form (a modal) that opens and contains a textbox to enter some text and then our program finds and highlights the searched text in the RichTextBox (in the calling form). In order to select the RichTextBox element in the calling form, we can use the .Controls.OfType<T>() method:

private void findHltBtn_Click(object sender, EventArgs e)
{
    var StrBox = _callingForm.Controls.OfType<RichTextBox>().First(ctrl => ctrl.Name == "richTextBox1");
    StrBox.SelectionBackColor = Color.White;

    var SearchStr = findTxtBox.Text;
    int SearchStrLoc = StrBox.Find(SearchStr);

    StrBox.Select(SearchStrLoc, SearchStr.Length);
    StrBox.SelectionBackColor = Color.Yellow;
}

Also in the same class (modal's form), to access the calling form use the technique mentioned in the @CuiousGeek's answer:

public partial class FindHltModalForm : Form
{
        private Form2 _callingForm = null;
        public FindHltModalForm()
    {
        InitializeComponent();
    }
    public FindHltModalForm(Form2 CallingForm)
    {
        _callingForm = CallingForm;
        InitializeComponent();
    }
//...

Upvotes: 0

CharithJ
CharithJ

Reputation: 47490

If ChildForm wants to access the ParentForm

Pass ParentForm instance to the ChildForm constructor.

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

    public string ParentProperty{get;set;}

    private void CreateChild()
    {
         var childForm = new ChildForm(this);
         childForm.Show();
    }
}

public partial class ChildForm : Form
{
    private ParentForm parentForm;

    public ChildForm(ParentForm parent)
    {
        InitializeComponent();

        parentForm = parent;
        parentForm.ParentProperty = "Value from Child";
    }   
}

Upvotes: 2

this. __curious_geek
this. __curious_geek

Reputation: 43207

Making them Singleton is not a completely bad idea, but personally I would not prefer to do it that way. I'd rather pass the reference of one to another form. Here's an example.

Form1 triggers Form2 to open. Form2 has overloaded constructor which takes calling form as argument and provides its reference to Form2 members. This solves the communication problem. For example I've exposed Label Property as public in Form1 which is modified in Form2.

With this approach you can do communication in different ways.

Download Link for Sample Project

//Your Form1

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

    private void button1_Click(object sender, EventArgs e)
    {
        Form2 frm = new Form2(this);
        frm.Show();
    }

    public string LabelText
    {
        get { return Lbl.Text; }
        set { Lbl.Text = value; }
    }
}

//Your Form2

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

    private Form1 mainForm = null;
    public Form2(Form callingForm)
    {
        mainForm = callingForm as Form1; 
        InitializeComponent();
    }

    private void Form2_Load(object sender, EventArgs e)
    {

    }

    private void button1_Click(object sender, EventArgs e)
    {
        this.mainForm.LabelText = txtMessage.Text;
    }
}

alt text
(source: ruchitsurati.net)

alt text
(source: ruchitsurati.net)

Upvotes: 34

Dwight
Dwight

Reputation: 730

Access the form's controls like this:

formname.controls[Index]

You can cast as appropriate control type, Example:

DataGridView dgv = (DataGridView) formname.Controls[Index];

Upvotes: 6

Joe Dabones
Joe Dabones

Reputation: 91

It's easy, first you can access the other form like this: (let's say your other form is Form2)

//in Form 1
Form2 F2 = new Form2();
foreach (Control c in F2.Controls)
         if(c.Name == "TextBox1")
            c.Text = "hello from Form1";

That's it, you just write in TextBox1 in Form2 from Form1.

Upvotes: 1

user8931966
user8931966

Reputation:

There is one more way, in case you don't want to loop through "ALL" controls like Joe Dabones suggested. Make a function in Form2 and call it from Form1.

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

    public void SetIndex(int value)
    {
        lsbMyList.SelectedIndex = value;
    }
}

public partial class Form1 : Form
{
    public Form2 frm;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        frm=new Form2();
        frm.Show();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        frm.SetIndex(Int.Parse(textBox1.Text));
    }
}

Upvotes: 2

ColinCren
ColinCren

Reputation: 615

I usually use the Singleton Design Pattern for something like this http://en.wikipedia.org/wiki/Singleton_pattern . I'll make the main form that the application is running under the singleton, and then create accessors to forms and controls I want to touch in other areas. The other forms can then either get a pointer to the control they want to modify, or the data in the main part of the application they wish to change.

Another approach is to setup events on the different forms for communicating, and use the main form as a hub of sorts to pass the event messages from one form to another within the application.

Upvotes: 1

Related Questions