How to update UI from one form to another form - c#

I have Form1 which contains a combobox which show some number saved in Database and it also contain a button(butn2) which on click popups a another form and another button(butn1) which updates the combo from database.
Here on this form (Form2, Child form of some sort)i try to updat the data of the combobox of previous form(parent one) on button click by creating object of Form1
But when i open and see the combobox it still show the same data(it is not updated).
Is it possible to update the UI from combobox from one form to another ? My code is
Form1 code:
public Form1()
{
InitializeComponent();
}
Form1.Designer.cs:
Button butn1;
Button butn2;
ComboBox cmb1;
private void InitializeComponent()
{
cmb1 = new ComboBox();
butn1 = new Button();
}
this.butn1.Click += new System.EventHandler(this.button_Save_Click);
this.butn2.Click += new System.EventHandler(this.button_Save_Click2);
public void button_Save_Click(object sender, System.EventArgs e)
{
UpdateComboBoxFromMySQL.InsertdataInCombo(this.cmb1 ); //Here i add data in combox through database, the code is correct i verfied it
}
public void button_Save_Click2(object sender, System.EventArgs e)
{
Form2 frm2 = new Form2();
frm2.show();
}
Form2 code:
Button butn2 = new Button();
//first i add some data to database, which are added i have seen the table-columns by opening DB. Now i want to update the Combobox from that data
Form1 obj1 = new Form();
this.butn2.Click += new System.EventHandler(obj1 .button_Save_Click); //It calls the function button_Save_Click, i saw on debugging but still it do not update the data.
How to update this combobox of Form1 from Form2 button click?

You also can show form2 with parent form1
public void button_Save_Click2(object sender, System.EventArgs e)
{
Form2 frm2 = new Form2();
frm2.Show(this);
}
Then you can access to form1 through the Owner property of form2.
this.butn2.Click += new System.EventHandler(Owner.button_Save_Click);

Let's suppose that the name of your first Form is Foobar. In that case, instead of
Form1 obj1 = new Form();
this.butn2.Click += new System.EventHandler(obj1 .button_Save_Click);
which creates a new Form object, you need this:
Form obj1 = null;
for (int i = ((obj1 == null) && (Application.OpenForms.Count - 1)); i >= 0; i--)
{
if (Application.OpenForms[i].Name == "Foobar")
obj1 = Application.OpenForms[i];
}
if (obj1 != null)
{
this.butn2.Click += new System.EventHandler(obj1 .button_Save_Click);
}
Explanation: obj1 is initialized with null. A cycle is created to find the Form you want to find, the end sign being either completed iteration or the Form being found. If the Form is found, then obj1 is initialized. After the cycle, if obj1 was initialized, then you can use it, its members and methods, including, but not limited to button_Save_Click.

Related

Using CheckBoxes/Buttons from other forms

There are 2 different forms.
Form1 and Form2
Form1 has 6 different checkBoxes and one button.
If you press the button, form2 opens and form1 gets closed and and the special buttons get visible, which you checked in the checkboxes before.
There are 6 buttons on form2 but all are set as visible = false.
For example: CheckBox 2 and 6 are checked and you press the button.
Form2 opens and Button 2 and 6 are visible.
But I cant use the CheckBoxes and Buttons from the different forms. I already set the Checkboxes and Buttons as public in the designer.
Can anyone help? Sorry for my bad english, thanks in advance!
Add this EventHandler to the .Click event of the button on Form1:
//Click EventHandler for Button on Form1
private void button1_Click(object sender, EventArgs e)
{
//Create instance of Form2
Form2 f2 = new Form2();
//Check which CheckBoxes are checked
foreach(CheckBox checkbox in this.Controls.OfType<CheckBox>())
{
if (checkbox.Checked)
{
//Get number of Checkbox
string number = checkbox.Name.Replace("checkBox", string.Empty);
//Show the corresponding Button on Form2
Button button = f2.Controls.Find("button" + number, true).FirstOrDefault() as Button;
button.Visible = true;
}
}
//Show Form2
f2.Show();
//Close or hide Form1
this.Hide();
}
Note: Keep in mind that for this to work your CheckBoxes on Form1 have to be called:
checkBox1, checkBox2, checkBox3, ...
and the Buttons on Form2 have to be called:
button1, button2, button3, ...
you could also add or remove Buttons and CheckBoxes at any point. Just make sure they're named correctly.
Unrelated Note: Please take a look at this before you ask your next question. And welcome to SO! :)
I already set the Checkboxes and Buttons as public in the designer.
I assume this means you changed the Modifiers property of the Buttons on Form2 to Public?
If so, then when you create Form2 from Form1, simply do:
// ... from within Form1 ...
Form2 f2 = new Form2();
f2.button1.Visible = this.checkBox1.Checked;
f2.button2.Visible = this.checkBox2.Checked;
f2.button3.Visible = this.checkBox3.Checked;
f2.button4.Visible = this.checkBox4.Checked;
f2.button5.Visible = this.checkBox5.Checked;
f2.button6.Visible = this.checkBox6.Checked;
f2.Show();
As Klemikaze mentioned in the comments, a more correct approach would be to pass the states to an overloaded Form2 constructor:
// ... in Form1 ...
private void button1_Click(object sender, EventArgs e)
{
bool[] checkStates = new bool[] {
checkBox1.Checked, checkBox2.Checked, checkBox3.Checked,
checkBox4.Checked, checkBox5.Checked, checkBox6.Checked
};
Form2 f2 = new Form2(checkStates);
f2.Show();
}
Then in Form2:
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
public Form2(bool[] btnVisibleStates)
{
InitializeComponent();
for(int i=0; i<btnVisibleStates.Length; i++)
{
String btnName = "button" + (i + 1);
Button btn = this.Controls.Find(btnName, true).FirstOrDefault() as Button;
if (btn != null)
{
btn.Visible = btnVisibleStates[i];
}
}
}
}

C# Geting null value from other form [duplicate]

I have two forms. First one has one textbox.Second one has a devexpress data grid.
I want to achieve that:
first click a button and form2 opens.
if I click a row in the data grid in form2, this value should be shown inside the textbox in form1.(form1 is already opened.)
ı m a beginner. thanks for your help.
Form1 frm1 = new Form1();
frm1.textBox1.Text = gridView1.GetFocusedRowCellValue("ID").ToString();
frm1.Show();
when I do that, a new form opens. I dont want to open a new form. Form1 is already opened. I want to add values to its textbox.
Pass form1 as a reference to form2:
In your button click handler on form 1 to open form 2
private void Button_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2(this);
frm2.Show();
}
form2 code
private Form1 frm1;
// constructor (pass frm1 as reference)
public Form2(Form1 frm1) {
this.frm1 = frm1;
}
//put this in your event handler for a row click in the grid
frm1.textBox1.Text = gridView1.GetFocusedRowCellValue("ID").ToString();
you can try something like this.
When you click on frm1.SimpleButton this function will be called a show your Form2. On Form2 you have to set InnerProperty (from your datagrid?) a when you close Form2 you can use this property.
private void SimpleButton_Click(object sender, EventArgs e)
{
using (Form2 frm = new Form2())
{
frm.InnerProperty = "default text";
DialogResult result = frm.ShowDialog();
SimpleButton.Text = frm.InnerProperty;
}
}
Finally, I solved the problem.
Application.OpenForms["form1"].Controls["textBox1"].Text =
gridView1.GetFocusedRowCellValue("ID").ToString();
Thanks for help.

Invoke method from another form

I'm trying to write a program that can display sql databases. I have 2 forms and i want to invoke the displaytable method(which opens a new tabpage on the main form(Form1) for every selected table in the sql database) on Form1.The 2 forms are open at the same time and the second form (From2) is supposed to be closed after the displaytable method has been invoked.
Form1:
private void openDatabaseToolStripMenuItem1_Click(object sender, EventArgs e)//File/Database/Open Database
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
data = openFileDialog1.FileName;
}
cn = "Provider=Microsoft.JET.OLEDB.4.0; Data Source =" + data;
try
{
connection = new OleDbConnection(cn);
connection.Open();
Form2 DataSelect = new Form2();
DataSelect.Show();
}
catch (Exception exceptcion)
{
MessageBox.Show("Such Error! Very Problem: "+exceptcion);
}
}
public void displaytable() // displays selected table on new tabpage (and dgv)
{
for (int i = 0; i < Form2.selectedtabscount; i++)
{
string a = database.ElementAt(i);
TabPage page = new TabPage(a);
tabControl1.TabPages.Add(page);
}
}
Fomr2(doesn't work):
private void bt_select_Click(object sender, EventArgs e)
{
selectedtabscount = checkedListBox1.CheckedItems.Count;
Form1.displaytable();
this.Close();
}
I have no idea about how to invoke the displaytable method on Form1.
Form1.displaytable(); does not work, because displaytable is an instance method. Remember that Form1 is a class, i.e. a type. You cannot call it on the type Form1, instead you must call it on an instance of it.
You can pass an instance of Form1 to Form2 through constructor injection. Add a parameter to the constructor of Form2
private Form1 _form1;
public Form2(Form1 form1)
{
InitializeComponent();
_form1 = form1;
}
private void bt_select_Click(object sender, EventArgs e)
{
selectedtabscount = checkedListBox1.CheckedItems.Count;
_form1.displaytable();
this.Close();
}
In Form1 you would create an instance of Form2 like this:
Form2 DataSelect = new Form2(this);
Form1 passes its current instance to Form2 with the this keyword.
I also noted that you have the same problem with Form2.selectedtabscount. It would make much more sense if you added a parameter to the method displaytable
public void displaytable(int selectedtabscount)
{
for (int i = 0; i < selectedtabscount; i++) {
...
}
}
and then call it like this:
_form1.displaytable(checkedListBox1.CheckedItems.Count);
You are just creating a new instance of Form1. You are not showing it, you need to call the form1.Show () or form1.ShowDialog() to show the other form.
It's nearly the same problem as in this question: I need to access a form control from another class (C#)
You have two options:
pass a reference from Form1 to Form2 and use it in your bt_select_Click method
or (the better one): define an event in Form2 and subscribe to it from Form1 (use this sample)

Switching between forms and sending variable correctly

I am wondering how can I correctly switch between forms by button click event.
I have Form1 and Form2.
Form1 have: -TextBoxForm1
-ButtonForm1
Form2 have: -TextBoxForm2
-ButtonForm2
I would like to on_click ButtonForm1 event go to the Form2. Then I want to write some message to TextBoxForm2 and press ButtonForm2 it will go to the Form1 again and message from TextBoxForm2 will appear in TextBoxForm1.
Everything works fine, but I have one problem. When I close application and I wanna debug and start it again, some errors appear like:"application is already running".
Form1:
public static string MSG;
public Form1()
{
InitializeComponent();
TextBoxForm1.Text = MSG;
}
private void ButtonForm1_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
this.Hide();
//There is probably my fault but when I was trying this.Close(); everything shutted down
form2.Show();
}
Form2:
private void ButtonForm2_Click(object sender, EventArgs e)
{
Form1.MSG = TextBoxForm2.Text;
Form1 form= new Form1();
form.Show();
this.Close();
}
How can I do this correctly please? :) I am beginner, thank you!
I would not go the route of using a STATIC for passing between forms as you mention you are a beginner, but lets get the closing to work for you.
In your main form create a new method to handle an event call as Hans mentioned in the comment. Then, once you create your second form, attach to its closing event to force form 1 to just become visible again.
// Inside your Form1's class..
void ReShowThisForm( object sender, CancelEventArgs e)
{
// since this will be done AFTER the 2nd form's click event, we can pull it
// into your form1's still active textbox control without recreating the form
TextBoxForm1.Text = MSG;
this.Show();
}
and where you are creating form2
private void ButtonForm1_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
form2.Closing += ReShowThisForm;
this.Hide();
form2.Show();
}
and in your second form click, you should only need to set the static field and close the form
private void ButtonForm2_Click(object sender, EventArgs e)
{
Form1.MSG = TextBoxForm2.Text;
this.Close();
}
Easy solution is to use modal form. Display Form2 temporarily, when it is displayed Form1 is invisible.
var form2 = new Form2();
this.Visible = false; // or Hide();
form2.ShowDialog(this);
this.Visible = true;
And to pass data you can define property in Form2, to example:
public string SomeData {get; set;}
Form1 has to set SomeData, which you take in Shown and display. Same property can be used to get data from Form2 (before closing).
// form 1 click
var form2 = new Form2() { SomeData = TextBoxForm1.Text; }
this.Visible = false;
form2.ShowDialog(this);
this.Visible = true;
TextBoxForm1.Text = form2.SomeData;
// form 2 shown
TextBoxForm2.Text = SomeData;
// form 2 click
SomeData = TextBoxForm2.Text;
Close();

Adding panels from Form2 to form1(MainForm)

ok, I have 2 forms...On f1 is a flowlayoutPanel and a button that opens f2.
On f2 there are small panels, each is a diffrent color.
I want to do this:when I click on a panel from f2 a panel is created in FLP in f1 that has the same color and size. The problem is that when I click on the first panel on f2 nothing happens.
this is what I have so far:
f1
private void Add_Color_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.Show();
}
f2
Form1 f1 = new Form1();
private void panel1_Click(object sender, EventArgs e)
{
Panel pnl = new Panel();
pnl.BackColor = panel1.BackColor;
pnl.Size = panel1.Size;
f1.BackColor = panel1.BackColor;
f1.FLPMain.Controls.Add(pnl);
this.Close();
}
So your child form shouldn't need to know a thing about your first form. It sounds like you're creating something like a generic color picker tool. You should be able to use that same form somewhere else in your application where you need to pick a color as well, for example.
As a general rule it's best if a child form doesn't "know" about it's parent, it keep them decoupled, makes it easier to write each class separately without forcing the developer to be so knowledgeable about the other types in the project. It's actually not terribly hard.
So rather than having Form2 go and add a panel to Form1, it can just notify Form1 when it's chosen a color and a size. This is done through an event:
public class Form2 : Form
{
//define the event
public event Action<Color, Size> ColorChosen;
private void panel1_Click(object sender, EventArgs e)
{
//raise the event
var panel = (Panel)sender;
ColorChosen(panel.BackColor, panel.Size);
Close();
}
}
(Size note; by using sender here this same event handler can be added to all of the panels you want to be clickable, rather than having a ton of event handlers that do almost the same thing.)
Then on Form1 we just assign an event handler to this custom event where we create and add a new panel to the form:
Form2 child = new Form2();
child.ColorChosen += (color, size) =>
{
Panel panel = new Panel();
panel.BackColor = color;
panel.Size = size;
Controls.Add(panel);
};
child.Show();
You're creating a new instance of Form1 here:
Form1 f1 = new Form1();
But you want to add your panels on the existing one, so use:
Form f1 = Application.OpenForms['formname'];
Just do it this way
private void Add_Color_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2(this);
f2.Show();
}
class Form2
{
private Form1 _frm;
public Form2(Form1 frm)
{
//initialize + other code if required
_frm = frm;
}
private void Panel_Click(object sender, EventArgs e)
{
_frm.CreatePanel(/*param you need*/); //name it what ever you want
}
}
bassicaly something like that should do the job
/e there might be some typos but the idea is there

Categories