I have two forms. In first I have button forwarding me to second form and hiding the first one with this.Hide();
It looks like this:
Form1Streamer f1 = new Form1Streamer();
f1.Left = this.Left;
f1.Top = this.Top;
f1.Size = this.Size;
f1.Show();
this.Hide();
checkBox1.Checked = false;
It also takes it's position but it's not about it.
In second form I have a button which should after clicking Go back to the hidden form and make it visible again, but I can find no solution how to access it's properity.
I have some ideas but don't really know how to tag it. Any help appreciated.
You need to pass the reference of the first form to the second form in order to call any method of first form. Here is a simple Example that will demonstrate.
Below is my first form class
using System;
using System.Windows.Forms;
namespace Test_Desktop
{
public partial class FirstForm : Form
{
public FirstForm()
{
InitializeComponent();
}
private void showSecondFormButton_Click(object sender, EventArgs e)
{
SecondForm secondform = new SecondForm(this); //Passing the reference of current form i.e. first form
secondform.Show();
this.Hide();
}
}
}
And here is my second form class
using System;
using System.Windows.Forms;
namespace Test_Desktop
{
public partial class SecondForm : Form
{
private FirstForm firstForm = null;
public SecondForm()
{
InitializeComponent();
}
///
/// Overriding constructor
///
public SecondForm(FirstForm firstForm)
{
InitializeComponent();
this.firstForm = firstForm;
}
private void showFirstFormButton_Click(object sender, EventArgs e)
{
if(firstForm!=null)
{
firstForm.Show();
//
//Do some processing
//
this.Dispose();
}
}
}
}
You need the reference of hidden form in the second form. For that, change the constructor of Second form like this
public Form1Streamer(Form firstform)
{
InitilizeComponent();
this.firstForm=firstform;
}
private FirstForm firstForm;
Now you can show the First Form using reference firstForm
In first form, you need to change this code
Form1Streamer f1 = new Form1Streamer();
to
Form1Streamer f1 = new Form1Streamer(this);
Related
In my application I have two forms (see image below). Clicking on "Add" button shows the second "Add wireless network" form.
After filling the form and clicking on "OK", second form adds the new profile and updates the wifi network profiles in the first form. There is a RefreshProfiles function in the first form and I call it in the second form with this:
((MainForm)this.Owner).RefreshWiFiProfiles();
and the "Add" button's code is this:
private void AddButton_Click(object sender, EventArgs e)
{
NewNetworkForm newNetworkForm = new NewNetworkForm();
newNetworkForm.Owner = this;
newNetworkForm.ShowDialog();
}
This setup is working fine, but since the number of lines increased as I added new things, I wanted to divide the code. So I created a class to contain some functions.
namespace WirelessNetworkManager
{
public class Tools
{
public static void RefreshWiFiProfiles(ListView ListViewControl)
{
// clear old list
ListViewControl.Items.Clear();
// update it
}
}
}
I call the method in the first form with this:
Tools.RefreshWiFiProfiles(ProfilesListView);
and it's working fine. The problem is, since I need to update the profiles list from the second form too, I need to call this in NewNetworkForm. I can access and pass the ProfilesListView in MainForm because it's in there. How can I pass a control that is in MainForm to a method in NewNetworkForm and modify it? Or is there a better approach to do this?
File structure
MainForm.cs (WirelessNetworkManager.MainForm)
NewNetworkForm.cs (WirelessNetworkManager.NewNetworkForm)
Tools.cs (WirelessNetworkManager.Tools)
You can set the Modifiers property of your ProfilesListView in Form2 to Public or Internal (It's Private by default) then you can access ProfilesListView of Form2 like this : Form2.ProfilesListView
For example:
ProfilesList.Refresh(Form2.ProfilesListView);
Your mistake is : You are creating a new Form when you are using RefreshWiFiProfiles() method.
You should access to existing Form2, for example if Form2 is Owner of Form1, this code works :
Form ownerForm = (Form)this.Owner;
Tools.RefreshWiFiProfiles(ownerForm.ProfilesListView);
Here is the complete example:
Form1 declaration:
Add a ListView to Form1, Set it's Modifiers to Public and add some items in it.
Add a Button to show Form2
Add a Button to clear Form2 ListView
Form1 Code:
public partial class Form1 : Form
{
Form2 form2;
public Form1()
{
InitializeComponent();
}
private void btnShowForm2_Click(object sender, EventArgs e)
{
form2 = new Form2();
form2.Owner = this;
form2.Show();
}
private void btnClearForm2List_Click(object sender, EventArgs e)
{
Tools.RefreshWiFiProfiles(form2.lstViewOfForm2);
}
}
Form2 declaration:
Add a ListView to Form2, Set it's Modifiers to Public and add some items in it.
Add a Button to clear Form1 ListView
Form2 Code:
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void btnClearForm1List_Click(object sender, EventArgs e)
{
Form1 form1 = (Form1)this.Owner;
Tools.RefreshWiFiProfiles(form1.lstViewOfForm1);
}
}
Declaration of Tools Class:
public static class Tools
{
public static void RefreshWiFiProfiles(ListView listView)
{
listView.Clear();
}
}
I tried implementing this. __curious_geek's answer and it worked fine.
MainForm.cs
namespace WirelessNetworkManager
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void AddButton_Click(object sender, EventArgs e)
{
// passing "this" (MainForm) to the second form
NewNetworkForm newNetworkForm = new NewNetworkForm(this);
newNetworkForm.ShowDialog();
}
}
}
NewNetworkForm.cs
namespace WirelessNetworkManager
{
public partial class NewNetworkForm : Form
{
public NewNetworkForm()
{
InitializeComponent();
}
// a local variable to reference the first form (MainForm)
private MainForm mainForm = null;
// a second overloaded constructor accepting a form
public NewNetworkForm(Form callingForm)
{
// mainForm now refers to the first form (MainForm)
mainForm = callingForm as MainForm;
InitializeComponent();
}
private void OKButton_Click(object sender, EventArgs e)
{
// create wifi profile with user input
// accessing the ListView using this.mainForm
Tools.RefreshWiFiProfiles(this.mainForm.ProfilesListView);
this.Close();
}
}
}
Tools.cs
namespace WirelessNetworkManager
{
public class Tools
{
public static void RefreshWiFiProfiles(ListView ListViewControl)
{
ListViewControl.Items.Clear();
// iterate through wifi profiles and populate ListViewControl
}
}
}
Also the control element's (ListViewControl) Modifiers should be set to Public or Internal. Otherwise you'll get an error.
'WirelessNetworkManager.MainForm.ProfilesListView' is inaccessible due to its protection level
I have 2 forms. The second form is opened from a method in the first form and I wish to be able to update the textbox that exists within that second form.
Basically I have the following code:
private void sendAllButton_Click(object sender, EventArgs e)
{
SendConsoleGUI sendOutGUI = new SendConsoleGUI();
sendOutGUI.Show();
sendOutGUI.sendConsoleTextBox.Text = "Test";
}
When I press the button the second form (SendConsoleGUI form) opens but "Test" is never added to its textbox.
Am I doing something wrong here?
You need to use invoke method.
sendOutGUI.Invoke((MethodInvoker) delegate { sendOutGUI.sendConsoleTextBox.Text = "Test"; });
public partial class ParentForm : Form
{
public ParentForm()
{
InitializeComponent();
}
private void sendAllButton_Click(object sender, EventArgs e)
{
SendConsoleGUI sendOutGUI = new SendConsoleGUI("Test");
sendOutGUI.Show();
}
}
public partial class ChildForm : Form
{
public ChildForm(string str)
{
InitializeComponent();
sendConsoleTextBox.Text = str;
}
}
This will work for you if you only wish to update it when the ChildForm is initially created.
In my project I have a Settings form and a Main form.
I'm trying to call the Main form's MasterReset function from the Setting form, but nothing happens.
The Master form's Masterreset function looks like this.
public void MasterReset()
{
DialogResult dialogResult = MessageBox.Show("Are you sure you want to perform master reset? All settings will be set to default.", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
if (dialogResult == DialogResult.Yes)
{
string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string phonebook_path = path + "\\Phonebook\\Contacts.xml";
XmlDocument xDoc = new XmlDocument();
xDoc.Load(phonebook_path);
XmlNode xNode = xDoc.SelectSingleNode("People");
xNode.InnerXml = "";
xDoc.Save(phonebook_path);
listView1.Clear();
people.Clear();
}
else if (dialogResult == DialogResult.No)
{
return;
}
}
And I'm accessing it from the Settings form like this
private void btn_MasterReset_Click(object sender, EventArgs e)
{
Main f1 = new Main();
f1.MasterReset();
}
Why am I not seeing any results?
Do you know what composition over inheritance is?
In the form where you have MasterReset you should do something like this:
Llet's suppose that in your second form you have something like this, and let's suppose your "mainform" will be called "MasterForm".
public partial class Form1 : Form
{
private MasterForm _masterForm;
public Form1(MasterForm masterForm )
{
InitializeComponent();
_masterForm = masterForm;
}
}
Here's the code in your masterForm Class:
private void button2_Click(object sender, EventArgs e)
{
Form1 form1 = new Form1(this);
}
Here's in your form1:
private void btn_MasterReset_Click(object sender, EventArgs e)
{
_masterForm.MasterReset();
}
Hope this helps!
This worked for me: In your Program class, declare a static instance of Main (The class, that is) called Form. Then, at the beginning of the Main method, use Form = new Main(); So now, when starting your app, use
Application.Run(Form);
public static Main Form;
static void Main() {
Form = new Main();
Application.Run(Form)
}
Now, calling a function from another form is simple.
Program.Form.MasterReset(); //Make sure MasterReset is a public void
namespace F1
{
// Method defined in this class
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//This method I would like to call in other form
public void function()
{
MessageBox.Show("Invoked");
}
// opening the new form using button click
private void OpenNewForm_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.ShowDialog();
}
}
// This is second form
public partial class Form2: Form
{
public Form2()
{
InitializeComponent();
}
// on button click Form1 method will be called
private void button1_Click(object sender, EventArgs e)
{
var mainForm = Application.OpenForms.OfType<Form1>().Single();
mainForm.function();
}
}
}
There are multiple solutions possible. But the problem itself arise from the bad design. If you need something to be accessed by many, then why should it belong to someone? If, however, you want to inform something about anything, then use events.
Your mistake is what you are creating another instance of form1, thus MasterReset is operating with form, which is not even shown.
What you can do:
Make (as Ravshanjon suggest) a separate class to handle that MasterReset (and maybe something else). But also add to it an event. form1 and form2 can both subscribe to it and whenever either of them call MasterReset - both will react.
Create form dependency (as BRAHIM Kamel suggested): when you create form2, then pass to it form1 instance (as constructor parameter or by setting public property), to be able to call public non-static methods of form1.
As a quick, but relatively legimate solution, make this method static:
private static Form1 _instance;
public Form1()
{
InitializeComponents();
_instance = this;
}
public static void MasterReset()
{
// alot of code
_instance.listView1.Clear();
// alot of code
}
this way you can call MasterReset from any other form like this Form1.MasterReset(). Disadvantage of this method is what you can not have more than one instance of form2 (which is more likely anyway).
I understand your problem, you can declare your function as public static void(also listView1 and people should be static too). Then when you want to call to like this:
private void btn_MasterReset_Click(object sender, EventArgs e)
{
Main.MasterReset();
}
Ok so I have six variables in one form that all change when various methods are invoked via buttons.
In another form I have six corresponding labels. I want to take the variables from the first form and set the SomeLabel.text in the second form when the button on the first form is pressed.
I've been trying to do this in this fashion Name=Mainform.InitializeComponent.SomeLabel.Text; but that doesn't work. I know the InitializeComponent method is private. I've tried changing it to public but that didn't prove fruitful either(also not good coding). So I came here to ask how I would do this. I was thinking about using a get and set setup but I'm still unable to access the label from the first form. I didn't include my code because nothing is broken in it and all the pieces that are needed are in the post.
You can either share a variable using public/internal Method or using `public / internal properties'
using System;
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
Form2 frm = new Form2();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
frm.Show();
}
private void button1_Click(object sender, EventArgs e)
{
frm.SetTextLabel1("Hello world");
//or
frm.Label1Text = "HEllo world again";
}
}
}
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
//using method to set the value of label
public void SetTextLabel1(string value)
{
label1.Text = value;
}
//using property to set the value of label
public string Label1Text
{
set { label1.Text = value; }
}
}
}
Set Modifier property of label to Public. So you can access to label from Form object.
Well there's the quick and dirty way which you've already been provided. Or there's write a class to hold this common data ,add a method to call from form1's button that fires an event, that form2 subscribes to, reads the data and updates it's labels. They both know about the intermediate class but neither needs to know anything about the other.
Why don't you take those six variables as Public static in form2.
public partial class Form1 : Form
{
private void button1_Click(object sender, EventArgs e)
{
Form2.VariableLable1 = "a";
Form2.VariableLable2 = "b";
}
}
public partial class Form2 : Form
{
public static string VariableLable1,VariableLable2;
private void form_load(object sender, EventArgs e)
{
Lable1.Text = VariableLable1;
Lable1.Text = VariableLable2;
}
}
I have 2 Forms. Form1 creates Form2 like this:
public partial class Form1 : Form
{
private void button3_Click(object sender, EventArgs e)
{
Form2 AcqForm = new Form2();
AcqForm.Show();
string[] ret = AcqForm.fulldate;
MessageBox.Show(ret[27]);
}
}
public partial class Form2 : Form
{
public string[] fulldate; //Created in form 2
close(); //Need to get this string back on or before close event
}
How should I go about doing this?
You need to handle the Form2 instance's FormClosed event in the first form and access the public properties.
Using this snippet, you can get a little knowledge on it.
in Form1:
using(Form2 form2 = new Form2())
{
if(form2.ShowDialog() == DialogResult.OK)
{
MessagBox.Show(form2.fulldate);
}
}
In Form2:
public partial class Form2 : Form
{
public string[] fulldate {get; set;} // Create a Property
void CloseForm()
{
fulldate = "valueToReturn";
DialogResult = DialogResult.OK;
}
}
Assuming you want button3_Click to wait until AcqForm is closed before accessing fulldate, you'll first have to change AcqForm.Show(); to AcqForm. ShowDialog();. (Show() doesn't wait for it to close.)
As for the fulldate field – it will be accessible even after the form closes because the form still exist. SLaks' remark about it being a 'field' means that we have different names for different types of 'variables'. What you have declared in the class (without get and set) is called a field. A variable in a method is called a 'variable'.
If you still want to do something when AcqForm closes, do this:
In Form1's constructor, before the AcqForm. ShowDialog();:
AcqForm.FormClosing += AcqForm_FormClosing;
And in Form1's class:
void AcqForm_FormClosing(object sender, FormClosingEventArgs e)
{
//Whatever will be here will be done when the form is closing.
//Use 'FormClosed' for doing things AFTER the form has closed.
}