Search code examples
c#winformspicturebox

How to change a PictureBox image from another Form


I want to open form2 while form1 loads. Also, I want to change the Image of a PictureBox in form2 when an action is triggered in form1.

To open form2 while form1 loads I used this code:

private void MONITOR3_Load(object sender, EventArgs e)
{
    MONITOR4 mo4 = new MONITOR4(this);
    mo4.Show();
}

To change the Image of the PictureBox in form2 I used this code, which is must to be run after a condition is met:

if (textBox1.Text == @"QUEBEC - ALPHA - TANGO - ALPHA - ROMEO - ")
{
    MONITOR4 mo4 = new MONITOR4(this);
    mo4.pictureBox1.Image = Image.FromFile("D:/QResources/images/HIA.jpg");
}

Solution

  • There are two problems with your current code:

    • You don't have to create a new Form instance each time you need to set some of its properties: store a reference to this Form and use this reference to call public properties or methods of the Form.
    • You are trying to directly access a child Control's properties of another Form. Event though you can define a child Control public, you shouldn't and it's not necessary. A Form is a class like any other in this aspect: create a public method on the Form that provides means to modify a private property, without directly exposing a Control's property to direct access.
      It's simple, safer and more portable: if a Control needs to be modified (the name is changed, the type of Control is changed etc.), you don't need to go on a hunt to find where the old name/properties have been used in other classes.
      The public method will be the same and it's the only responsible to reference the current names, properties of the affected Control. A single place where the code, eventually, needs to be modified. You could also use a public event or implement INotifyPropertyChanged to notify the subscribers that some properties have changed.

    Here, I'm creating a reference to Monitor4 in the Monitor3 Form:

    Monitor4 mo4 = null;
    

    This reference will be use to call a public method (UpdatePictureBox) of Monitor4.

    Monitor3 Form:
    (I'm using the TextChanged event of a TextBox to select the Image to show in the Monitor4 PictureBox. Of course, it could be the Validate event or anything else that agrees with your design)

    public partial class Monitor3 : Form
    {
        Monitor4 mo4 = null;
    
        private void Monitor3_Load(object sender, EventArgs e)
        {
            mo4 = new Monitor4();
            //Show Monitor4 on the right side of this Form
            mo4.Location = new Point(this.Right + 10, this.Top);
            mo4.Show(this);
        }
    
        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            string newText = textBox1.Text;
            switch (newText) {
                case "[Some text 1]":
                    mo4.UpdatePictureBox(@"[Images1 Path]");
                    break;
                case "QUEBEC - ALPHA - TANGO - ALPHA - ROMEO - ":
                    mo4.UpdatePictureBox(@"[Images2 Path]");
                    break;
                case "[Some text 3]":
                    mo4.UpdatePictureBox(@"[Images3 Path]");
                    break;
            }
        }
    }
    

    Monitor4 Form:

    public partial class Monitor4 : Form
    {
        public void UpdatePictureBox(string imagePath)
        {
            if (File.Exists(imagePath)) {
                pictureBox1.Image?.Dispose();
                pictureBox1.Image = Image.FromFile(imagePath, true);
            }
        }
    }
    

    Sample result:

    Access a Form's Control from another class