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.
Related
i currently have one form and a few user control, i have a panel set from the Form1 - mainpanel, so that whenever i click a button, one of the user control will be showing on the mainPanel.
my problem is that one of the control(InfoSetting) has some other new buttons, and when i click it I would like the mainPanel to show the new user control. However, right now all other buttons from Form1 is working fine, but when I click on the InfoSetting button, nothing seems to show up.
here is my code from Form1
public partial class Form1 : MetroFramework.Forms.MetroForm
{
InfoSettings infoSetting;
CashSales cashSales;
PriceSetting priceSetting;
public Form1()
{
InitializeComponent();
infoSetting = new InfoSettings();
cashSales = new CashSales();
priceSetting = new PriceSetting();
}
protected void ButtonClicked(object sender, EventArgs e)
{
buttonHandler(sender);
}
public void buttonHandler(object sender)
{
Button button = sender as Button;
mainPanel.Controls.Clear();
if (button != null)
{
switch (button.Name)
{
case "HomeBtn":
infoSetting.Dock = DockStyle.Fill;
mainPanel.Controls.Add(infoSetting);
break;
case "cashSalesBtn":
cashSales.Dock = DockStyle.Fill;
mainPanel.Controls.Add(cashSales);
break;
case "settingBtn":
infoSetting.Dock = DockStyle.Fill;
mainPanel.Controls.Add(infoSetting);
break;
case "priceSettingBtn":
cashSales.Dock = DockStyle.Fill;
mainPanel.Controls.Add(cashSales);
break;
default:
mainPanel.Controls.Clear();
break;
}
}
}
and here is the code from the InfoSetting user control
public partial class InfoSettings : UserControl
{
public InfoSettings()
{
InitializeComponent();
}
private void priceSettingBtn_Click(object sender, EventArgs e)
{
Form1 form1 = new Form1();
form1.buttonHandler(sender);
}
}
as stuartd said you can add a call to your parent Form:
public partial class InfoSettings : UserControl
{
public InfoSettings()
{
InitializeComponent();
}
private void settingBtn_Click(object sender, EventArgs e)
{
Form1 form1 = (Form1) this.Parent;
form1.buttonHandler(sender);
}
}
It would probably be better to have a common class that you can access in both form and user control and have the code you want to run in a method there. Something like:
public class FormHelper
{
public void CodeIWantToRunIn2Places()
{
// Implementation Here
}
}
You can implement the above as a singleton so you have access in both places. Then in your form classes you could do:
FormHelper.Instance.CodeIWantToRunIn2Places();
In your event handler as well as in your user control.
You can make the Form 1 as "static" and also the method buttonHandler(object sender) as "static" as well.
Then inside the priceSettingBtn_Click, call the below function directly
Form1.buttonHandler(sender);
I would have a global object with a pointer to all the forms in the application.
public Global
{
public Form1 MainForm;
public Dialog1 D1;
...
}
public static Global = new Global();
In as each form is created
Global.MainForm = form1;
then you can go
private void priceSettingBtn_Click(object sender, EventArgs e)
{
Global.MainForm.buttonHandler(sender);
}
As other have said , its probably better to not call the click handler, its better to have this code and the real click handler call a business logic level function
How do i pass data from a form i opened in userControl back to the userControl?
userControl code:
public AdminControl()
{
InitializeComponent();
SetGridColomns();
}
private void btnEditInfo_Click(object sender, EventArgs e)
{
Form editForm = new EditForm();
if (editForm.ShowDialog() == DialogResult.OK)
{
// trying to get Owner2 here but failing
}
}
Form Code:
public partial class EditForm : Form
{
public CompanyOwner Owner2;
public EditForm()
{
InitializeComponent();
Owner2 = new CompanyOwner();
}
private void btnSave_Click(object sender, EventArgs e)
{
Owner2.Address = tbAddress.Text;
Owner2.CompanyName = tbCompanyName.Text;
Owner2.Email = tbEmail.Text;
Owner2.Phone = tbPhone.Text;
}
}
When i try to get editForm.Owner2 nothing shows up. I tried making it static, using strings instead of class and still nothing. Where im going wrong?
Nvm i find the mistake ... i should use EditForm instead of Form:
EditForm editForm = new EditForm();
I have set up my program so that the user can enter a new line into the combo box via a text box on a separate form (Popup form). So far the program allows the new entry and closes the popup form when the user presses the "Accept" button however the entry does not appear in the combobox and the entry is not saved.
Currently the only way to view the new entry is by the .ShowDialog(); function which opens a second instance of the first form.
Form 2
namespace RRAS
{
public partial class NewRFRPopup : Form
{
public NewRFRPopup()
{
InitializeComponent();
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.Close();
}
private void btnAccept_Click(object sender, EventArgs e)
{
formRRAS main = new formRRAS();
string newRFR = txtNewRFR.Text;
main.AddRFR(newRFR);
this.Close();
main.ShowDialog();
}
private void NewRFRPopup_Load(object sender, EventArgs e)
{
}
}
}
AddRFR in Form 1
public void AddRFR(object item)
{
cmbRFR.Items.Add(item);
}
you are creating a new instance of your form1 in the accept handler:
formRRAS main = new formRRAS();
(which is why when you call showdialog you get another formRRAS appearing).
You need to pass the original formRRAS to the popup and call AddRFR on the instance passed through. I'd pass it on the constructor of the popup - i.e.
public partial class NewRFRPopup : Form
{
formRRAS _main;
public NewRFRPopup(formRRAS main)
{
InitializeComponent();
_main = main;
}
and then in your Accept handler:
string newRFR = txtNewRFR.Text;
_main.AddRFR(newRFR);
this.Close();
and of course to show the popup from formRRAS
NewRFRPopup popup = new NewRFRPopup (this);
popup.ShowDialog();
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'd like to create, say 32 Windows Forms based upon a single template Form, and those instances should be linked to each other. That is, every Form has a button for calling the next instance and so on. I am able to create as many forms as I like but how would I link those instances together ?
This is what I use to create several child forms:
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
ChildForm child = new ChildForm();
child.Show();
}
}
Sequence of events would be like:
User starts application, main form is displayed (only has "Open Child" button)
User pushes "Open child" button, first instance of child form opens
first child form (caption "Child Form 1") has button "Open Child Form 2"
if user pushes "Open Child Form 2" child form 1 is hidden and child form 2 is displayed
if the last child form is reached wrap-around to child form 1
Any ideas are welcome !
regards
Chris
You can create a static collection of the form, in the constructor add the form instance to the list (and remove it during dispose). To figure out the next form, you can find the index of the current form and grab the next form in the list based on that. Create a form with two buttons and modify it as below to test it out.
public partial class Form1 : Form
{
static List<Form1> formList = new List<Form1>();
public Form1()
{
InitializeComponent();
formList.Add(this);
}
private void button1_Click(object sender, EventArgs e)
{
int idx = formList.IndexOf(this);
int nextIdx = (idx == formList.Count()-1 ? 0: idx+1 );
Form1 nextForm = formList[nextIdx];
nextForm.changeTextAndFocus("next form: " + nextIdx);
}
// moves to the next form and changes the text
public void changeTextAndFocus(string txt)
{
this.Focus();
this.Text = txt;
}
//Creates 5 forms
private void button2_Click(object sender, EventArgs e)
{
for (int i = 0; i < 5; i++)
{
Form1 newForm = new Form1();
newForm.Show();
}
}
}
I don't really know what you are planning to do :). If you want to count several forms, you can add a property Number to the form. And searching upwards from there.
Mainform;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
ChildForm first = new ChildForm();
first.Number = 1;
first.Show();
}
}
ChildForm
public partial class ChildForm : Form
{
public ChildForm()
{
// createButton here
}
private void button_Click(object sender, EventArgs e)
{
ChildForm _childForm = new ChildForm();
_childForm.Owner = this;
_childForm.Number = this.Number + 1;
this.Hide();
_childForm.Show();
}
public void FirstChildForm()
{
if (this.Number != 1) //maybe not that static
{
(this.Owner as ChildForm).FirstChildForm();
this.Close(); // or hide or whatever
}
}
public int Number
{ get; set; }
}
Not tested code, hope this helps a bit :).