Resize form from another form - c#

I am running two forms simultaneously and I am trying to resize Form1 by calling a Form1 method with an event in Form2. With the following code the proper size values are displayed in the console, but the size of Form1 does not change. I have tried a number of approaches but I don't see why this does not work.
In Form1:
public void ResizeForm()
{
Console.WriteLine(this.Size.ToString());
this.Size = new System.Drawing.Size(600, 300);
}
In Form2:
private void ResizeCheckbox_CheckedChanged(object sender, EventArgs e)
{
Form1 form = new Form1();
form.ResizeForm();
}

You should pass the instance of the current Form1 to the second form. Add an instance in Form2 and then get it from Form1
Form2
Form1 _form1;
public Form2(Form1 form1)
{
InitializeComponent();
_form1 = form1;
}
private void ResizeCheckbox_CheckedChanged(object sender, EventArgs e)
{
_form1.ResizeForm();
}
Then open Form2 in the main form like this.
Form2 form2 = new Form2();
form2.Show((Form1)this); //I'm not sure if you need to cast "this" to From1

Form1 form = new Form1(); creates a new form, resizes it, and then forgets it. So, this is completely pointless. The ResizeForm() method does get invoked, but on the wrong instance of Form1. From your description, you should have some other instance of Form1 somewhere, the instance that you are actually displaying to the user. You need to access that instance from within Form2. If you do not have access to the correct instance of Form1 from within Form2, you must somehow pass it, so that Form2 has it. Creating a new instance of Form1 is not going to resize the original instance of Form1.

Related

How to make form2 update when value changed in form1

In C# I have two forms "Form1" and "Form2". Form1 creates images that are stored in a folder. Form2 displays the number of images in that folder.
Say I have made 2 images with Form1 and then I open Form2. Form2 now says there are 2 images. Now while keeping both forms open I want to be able to add a new image and Form2 updates. At the moment if I use Form1 to add more images while Form2 is open Form2 continues to display the number of images that were in the folder when Form2 opened.
I have found solutions that involve Form2 closing and reopening but I don't want this. It's jarring for the user having windows opening and closing every time they press a button. I just want Form2 to update live as I make changes with Form1.
Any help would be greatly appreciated!! Thanks!
You can do this with public method in Form2
In Form1 you need to save Form2 object in property
FORM 1
public partial class Form1 : Form
{
public Form2 MyProperty { get; set; }
public Form1()
{
InitializeComponent();
}
// for opening form 2
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.Show();
MyProperty = f2;
}
// adding new image
private void button_ADD_Click(object sender, EventArgs e)
{
MyProperty.updateCounter();
}
}
When you add new image, then you can call the metoh from Form2 to update counter.
In FORM 2 you need crate PUBLIC method to update counter
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
// default value
label1.Text = "0";
}
// update counter
public void updateCounter()
{
label1.Text = (int.Parse(label1.Text) + 1).ToString();
}
}
You may want to take a look at events and delegates. Basically, whenever you do something to Form1 that can affect other forms, you want to trigger an event. In Form2, you have a method which you call whenever that event triggers. This way you can have multiple forms open, and as long as you set them to "listen" to a given event, they can all react.
You can read more about them here, in the Microsoft Documentation.

Add a datagridview column from another form

I have two forms and a datagridview which is in the form1.Im trying to add a new column by clicking in a button from form2.Like that:
Form2
private void button1_Click(object sender, EventArgs e)
{
Form1 form1 = new Form1();
form1.dataGridView1.Columns.Add("test" , "test");
}
How can I do that?
Form1 form1 = new Form1();
This will not work as your real form1 is already there, I pressume. Instead create a reference to it in form2 and load it in form2's constructor!
Here are the steps:
the local reference to form1 in form2's variables: Form1 form1
When opening form2 pass a reference to form1 in the constructor:
form2 = new Form2(this);
Store it in the local refence in the constructor on form2:
public Form2(Form1 form1_)
{
InitializeComponent();
form1 = form1_;
}
Now you are all set to use Form1 and its public properties and controls. To use form1.dataGridView1 you must make it public first, though. (Or create a public reference to it..)

Getting parent form name of a form

I have a Form (form3)which could be opened from two other forms. Form1 and Form2.
how can I get which one is the parent of the form3?
The term "parent" has a very strict definition in Windows. The Form class derives from Control like all UI classes do, but it is pretty distinct, it is a top-level window. Very unlike the other controls, like Button and TextBox, they are child windows inside a parent window. The parent of a Form is the desktop window, pretty unlikely that you are interested in that one.
So it is pretty meaningless to talk about "the parent of Form3", it is the same parent as Form1 and Form2 and it doesn't help you at all to distinguish which one might have displayed the Form3 window.
Windows does have a way to associate two top-level windows with each other, it has the notion of an owner window. It is meant to implement a tool window or a dialog, an owned window is always displayed on top of its owner and is minimized along with its owner. Creating an owned window is simple:
var toolWindow = new Form3();
toolWindow.Show(this);
This Show() overload takes an argument that indicates its owner, this can be a reference to a Form1 or Form2 object, depending on where this code appears. Inside the Form3 class, you can find the owner back by using the Owner property.
Which is fairly unlikely what you are really talking about, Winforms is frequently a programmer's first introduction to object-oriented programming and dealing with object references is often confounding. If you need a reference to a logical parent in Form3 then just write the code so you pass that parent. Which you do by giving the Form3 class a constructor:
private Form logicalParent;
public Form3(Form parent) {
InitializeComponent();
logicalParent = parent;
}
And creating the window in Form1 or Form2 just takes:
var form = new Form3(this);
form.Show();
You can further improve this code in an object-oriented way by designing a base class for Form1 and Form2, one that has members in common that a class like Form3 would be interested in. Or better yet, an interface that both Form1 and Form2 implement, that reduces the coupling significantly. Last but not least, use events to allow Form3 to notify its logical parent. Probably what you are really looking for.
You can access the Parent form from the Child like this,
Say MainForm is the Form1
MainForm parent = (MainForm)this.Owner;
Or If you want to find the Parent from the hierarchy,
In the Form1 you instantiate Form2 somewhere and pass it a reference to Form1 in ctor:
Form2 f2 = new Form2(this);
In the class definition of Form2 add a field:
private Form1 m_form = null;
In the constructor of the second form set that field:
public Form2(Form1 f)
{
m_form = f;
}
Inside your Form3 you can do this:
var form1 = this.Parent as Form1;
if(form1 != null)
{
//form1.Text
}
var form2 = this.Parent as Form2;
if(form2 != null)
{
//form2.Text
}
Normally I get a name of Parent of control via
MessageBox.Show(control_Name.Parent.Name);
but now we are finding the Parent of a form, so we cannot use the same method because we don't even need to have real Parent and Client relationship to call a Form. So we will have NullReferenceException when we do
MessageBox.Show(this.Parent.Name);
in Form3.
By doing these in Form 1 and Form2 and Form3, I can call the Form3 from both forms.
Form1
Form3 frm3;
public Form1()
{
InitializeComponent();
frm3 = new Form3(this);
}
private void button1_Click(object sender, EventArgs e)
{
frm3.Show();
}
Form2
Form3 frm3;
public Form2()
{
InitializeComponent();
frm3 = new Form3(this);
}
private void button1_Click(object sender, EventArgs e)
{
frm3.Show();
}
Form3
public Form3(Form parent)
{
InitializeComponent();
}
As my conclusion, if the Parent form can only have one, then both of Form1 and Form2 is not Form3 parent Form because either one is not exist but the other one still can call Form3 out. If the Parent form can have more than one, then I think both of Form1 and Form2 are parent forms of Form3.
By the way, if the Parent Form minimized, the Child Form also minimized, then we can make Form1 as Parent Form (or actually owner form) of Form3
Form1
Form3 frm3;
public Form1()
{
InitializeComponent();
frm3 = new Form3(this);
this.AddOwnedForm(frm3);
}
OR
we set the owner of Form3 to the Form who calling it by
Form3
public Form3(Form parent)
{
InitializeComponent();
this.Owner = parent;
}
If you are not agree with me, please give me clear definition of Parent form and Child form.thanks. I try to explain from my point of view and hope someone correct me if I am wrong.

How do I refrence form1 from form2 without causing an infinite loop?

In my main form (form1) I have checkboxes that when checked should also check the corresponding box in form2. I also want if checkboxes in form2 are checked they check the corresponding boxes on form1. The problem that I believe I am encountering is that form1 can make an object of form2 to reference, however if I instantiate an object of form1 within form2 I believe it creates an infinite loop? Any help figuring this out is appreciated.
Form1 creates an object of form2:
Form2 formSettings = new Form2();
Now when I have an event I can update form2:
public void logScanResultsToolStripMenuItem_Click(object sender, EventArgs e)
{
if (logScanResultsToolStripMenuItem.Checked)
{
formSettings.chbxLogScanResults.Checked = true;
}
else
{
formSettings.chbxLogScanResults.Checked = false;
}
}
But if I try to do something similar in Form2:
Form1 form1 = new Form1();
So that I can reference form1's menu item from within form2(formSettings) I end up creating an object (form1) that calls to make an object of Form1, which within Form1 includes a call to create an object of Form2 and thus an endless loop.
You shouldn't create an instance every time a checkbox is checked off. You need to maintain the instances alive and hide/show them as needed. Also, the constructor of one of the forms should receive the other one as parameter in its constructor so they can reference each other.
Hopefully this is clear enough. It isn't a straight out answer as you really dont have much detail in your question.
Basically you have two forms, Form1 and Form2, which will be throwing events (OnChangeEvent?) on the change of some checkboxes.
Form1 listens for events from Form2 and Form2 does the same from Form1.
If Form1's event listen receives a OnChangeEvent and changes its checkbox then it should raise an OnChangeEvent. If on the other hand it doesn't change its checkbox (as it already has the correct value) then it should not raise an OnChangeEvent.
In the body of Form1 you need to declare Form2 to hold an instance of it for referencing and to open it. When you call the Form2.Show method from Form1, you will pass a reference of itself to Form2 which you then can use to gain access back to Form1.
public partial class Form1 : Form
{
Form2 form2 = new Form2();
public Form1()
{
InitializeComponent();
}
private void form1Button_Click(object sender, EventArgs e)
{
form2.Show(this);
}
private void form1CheckBox_CheckedChanged(object sender, EventArgs e)
{
form2.ChangeCheck(form1CheckBox.Checked);
}
public void ChangeCheck(bool isItChecked)
{
form1CheckBox.Checked = isItChecked;
}
}
In Form2 you can now reference Form1 as the owner.
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void form2CheckBox_CheckedChanged(object sender, EventArgs e)
{
((Form1)this.Owner).ChangeCheck(form2CheckBox.Checked);
}
public void ChangeCheck(bool isItChecked)
{
form2CheckBox.Checked = isItChecked;
}
}

How can I Change something in a Form1 from a DialogBox?

Lets say I have two forms ( Form1 And Form2 ).
Form1 has a PictureBox
Form2 I has an OpenFileDialog
Form1 is the main form, so when I run the project I see Form1.
How can I change the Image in the PictureBox in Form1 from Form2?
How do I pass a value from a child back to the parent form?
Basically, expose the value that gets returned in the open file dialog with some property and let the parent form grab it.
In the Program.cs file you can set any value, either FormOptions to the form's instance .
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var frm = new Form1();
// Add the code to set the picturebox image url
Application.Run(frm);
}
In addition you can add the Constructor to Form1 and pass the parameter via constructor.
Pass one form as a parameter to a constructor of the second form or add a method that passed the reference. After you have the reference to your form you can do whatever you want with the from.
Whether to share picture box as a public member is up to you. However, I would suggest making a public method SetImage() in the first form. Second form would call form1.SetImage().
[Update]
Wait, why do you need to set image from OpenFileDialog, you just need receive fileName from the dialog, and then open the file and load into the form.
Like this:
private void button1_Click(object sender, EventArgs e)
{
using (var dialog = new OpenFileDialog())
{
var result = dialog.ShowDialog();
if (result != DialogResult.OK)
return;
pictureBox1.Image = Image.FromFile(dialog.FileName);
}
}
This is code inside of Form1.
[Update]
Here is the basic idea how to access one form from another.
public class MyForm1 : Form
{
public MyForm1()
{
InitializeComponent();
}
public void SetImage(Image image)
{
pictureBox1.Image = image;
}
private void button1_Click(object sender, EventArgs e)
{
var form2 = new Form2(this);
form2.Show();
}
}
public class MyForm2 : Form
{
private MyForm1 form1;
public MyForm2()
{
InitializeComponent();
}
public MyForm2(MyForm1 form1)
{
this.form1 = form1;
}
private void button1_Click(object sender, EventArgs e)
{
form1.SetImage(yourImage);
}
}
You can very simply do this.
At first change your code(in Form1) that show Form2 to looks like this:
<variable-of-type-Form2>.ShowDialog(this);
or if you dont want form2 to be modal
<variable-of-type-Form2>.Show(this);
Next when you got path to image, you can access pictureBox like this
((PictureBox)this.Owner.Controls["pictureBox1"]).Image=Image.FromFile(<filename>);
Assume that you have PictureBox on Form1 with name "pictureBox1"
Ideally, you want to structure your code in a ModelViewController pattern. Then, you simply have a reference in your model to the image in the picture box. When interacting with the OpenFileDialog in Form2, you would call your model adapter interfaces hooked into the views (Form1 and Form2) to change the image being held in the model. In short, you need a callback from the view to the model. If you don't want to redesign your code to be MVC, simply have a shared object holding the image reference that both Form1 and Form2 receive in their constructors, so they can both modify it.

Categories