retrieving the updated value of variable A on form2 closing? C# - c#

This is a very simple question yet I couldn't find a solution for it (I am not a pro programmer sorry if this is primitive!). In Form1 I have a variable called "A" and it's value is 1. I send this to Form2 and change the value to 2. And on Form2 closing I need to send the updated value to Form1. This last part I don't know how to do that and I need your help. How can I retrieve the updated value of variable A on form2 closing?

If you have a value that is changed by Form2, and that value is managed by Form2, you can expose it as a property of Form2, e.g.
public class Form2
{
public string MyValue
{
get { return myValue; }
}
}
and then you can retrieve it like
Form2 f2 = new Form2();
f2.ShowDialog();
string theValue = f2.MyValue;
In general you may want to check the DialogResult returned by ShowDialog() to see if the user pressed e.g. the OK or Cancel button. I'm not sure if you need that in this particular case.
UPDATE
If Form2 is not a dialog, you can instead use a callback pattern to inform Form1 that Form2 is closing to allow Form1 to retrieve any values that it needs from Form2. Alternatively you can have the callback directly supply the value you need.
Specifically, you could pass a Func<T> to Form2 that points to a callback method in Form1. Form2 would then call that Func<T> when it determines that it is closing. Here, T represents the type of variable that you want passed back to Form1.
Here's an example that assumes T is a string:
public Form2 : Form
{
public void MyCallback(string value) { /* Do something with value */
}
public Form1 : Form
{
Func<string> callback;
public Form1(Func<string> callback)
{
this.callback = callback;
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
if (callback != null) callback(myValue);
}
}

WinForm has an Event called FormClosing. Right click on the form and choose properties, on right side of IDE you will get properties. There will be an icon like "lightning" in yellow color. You will find the FormClosing event there. Now add the code you want when form is closing

You could handle the the form2.FormClosing event on form1. There you can retrieve your value form2.B (provided that it is publicly accessible) on form1 as form2 is closing.
form2.FormClosing += OnFormBClosing;
private void OnFormBClosing(object sender, FormClosingEventArgs eventArgs)
{
A = form2.B;
}

Use from closing event
private void Form2_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
//update
}
MSDN Library

It would probably better if you can post your actual source code.
I suppose that you open Form2 from Form1, is it right? If true, I think it would be probably better to write something like this that trying to update form1 from form2 closing event.
Form2 form2 = new Form2();
form2.A = this.A; // here this = form1
if (DialogResult.OK == form2.ShowDialog())
{
// So here, retrieve the property from form2.
this.A = form2.A;
}

Related

Having problem to close a second windows form without closing the main form

In a c# I have two forms: Windows Form1 & Windows Form2.
When I click on a link label in Form1, the second form is shown. But when I close the second form, my first Windows form closes too.
my main form is:
namespace Windows_Forms_Basics
{
public partial class ShowLocationOnMapForm : Form
{
private string latitude;
private string longitute;
private GeoCoordinateWatcher watcher = new GeoCoordinateWatcher();
public ShowLocationOnMapForm()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
watcher = new GeoCoordinateWatcher();
// Catch the StatusChanged event.
watcher.StatusChanged += Watcher_StatusChanged;
// Start the watcher.
watcher.Start();
}
private void button_ShowOnMap_Click(object sender, EventArgs e)
{
textBox_Latitude.Text = latitude;
textBox_Longtitude.Text = longitute;
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "<Pending>")]
private void Watcher_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e) // Find GeoLocation of Device
{
try
{
if (e.Status == GeoPositionStatus.Ready)
{
// Display the latitude and longitude.
if (watcher.Position.Location.IsUnknown)
{
latitude = "0";
longitute = "0";
}
else
{
latitude = watcher.Position.Location.Latitude.ToString();
longitute = watcher.Position.Location.Longitude.ToString();
}
}
else
{
latitude = "0";
longitute = "0";
}
}
catch (Exception)
{
latitude = "0";
longitute = "0";
}
}
private void label1_Click(object sender, EventArgs e)
{
}
private HelpForm form2 = new HelpForm();
private void linkLabel_help_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
this.Hide();
form2.Show();
}
}
}
and my second form is:
namespace Windows_Forms_Basics
{
public partial class HelpForm : Form
{
public HelpForm()
{
InitializeComponent();
}
private void HelpForm_Load(object sender, EventArgs e)
{
}
private void button_BackToForm1_Click(object sender, EventArgs e)
{
ShowLocationOnMapForm form1 = new ShowLocationOnMapForm();
this.Hide();
form1.Show();
}
}
}
Do you have any idea how to tackle this problem?
I am guessing you may be “confusing” forms and one forms “ability” to access another form. Let’s start by taking a look at the bit of code in your initial question…
private HelpForm form2 = new HelpForm();
private void linkLabel_help_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) {
this.Hide();
form2.Show();
}
This code is called from (what appears to be) a Form named ShowLocationOnMapForm.
On this form is a LinkLabel named linkLabel_help and its LinkClicked event is wired up and is shown above.
In addition, there appears to be a “global” variable form2 that is a HelpForm object (first line in the code above), which is another form. It is unnecessary to create this “global” form variable in the ShowLocationOnMapForm. …. However, we will continue as it is not pertinent at this point.
When the user “clicks” the `LinkLabel’ the above method will fire.
On the first Line in the method…
this.Hide();
Is going to “hide” the current form ShowLocationOnMapForm … and “show” the second form (HelpForm) with the line…
form2.Show();
On the surface, this may appear correct, however, there is one problem that I am guessing you are missing. The problem is…
How are you going to “unhide” the first form ShowLocationOnMapForm?
The second form (HelpForm) is “shown”, however, it isn’t going to KNOW anything about the first form. In this situation the first form is basically LOST and you have no way of accessing it. Therefore when you attempt the line… form1.Show(); in the second form, the compiler is going to complain because its not going to know what form1 is. In this code, there is NO way to get back to the first form. It is not only hidden from the user, but from the second form’s perspective the “CODE” can’t see it either!
Your faulty solution is not only “creating” another form1 but it is also doing the same with the second form.
Given this, it appears clear, that if you want to keep access to the first form… then you are going to have to use a ShowDialog instead of Show OR pass the first form to the second form.
Since it is unclear “how” you want these forms to interact, I can only proffer two (2) ways that you can use to at least keep access to the first form.
1) Use ShowDialog instead of Show when displaying the second form. It may look like …
private void linkLabel_help_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) {
HelpForm form2 = new HelpForm();
this.Hide();
form2.ShowDialog();
this.Show();
}
In the code above, the ShowDialog is going to “STOP” code execution in the first form and will wait for the second form (form2) to close. When executed, the first form is hidden, then the second form is shown, however, unlike the Show command, the line this.Show(); will not be executed until the second form closes. I am guessing this may be what you are looking for.
2) Pass the first form to the second form giving the second form “access” to the first form.
This will require that the second form has a “constructor” that takes a ShowLocationOnMapForm object as a parameter. With this, the second form can create a “global” variable of type ShowLocationOnMapForm that “points” to the first form. The constructor may look like…
private ShowLocationOnMapForm parentForm;
public HelpForm(ShowLocationOnMapForm parent) {
InitializeComponent();
parentForm = parent;
}
In the first form, you would instantiate the second form with...
HelpForm form2 = new HelpForm(this);
With this approach, the second form will have total access to the first form. You could add the “back” button as you describe and simply execute the line…ParentForm.Show(); However, I recommend you also wire up the second forms FormClose event and show the first form, otherwise, if the user clicks the close button (top right) and doesn’t click the “back” button, then you will have LOST the first form again.
Without knowing “exactly” how you want these forms to interact it is difficult to proffer a complete solution.
There are also other ways to accomplish this, however these should work for most cases.
I hope this makes sense and helps.
I tried to solve this problem by placing a 'Back to Form1' button in Form2. Which works, and the solution is as follows:
on my Form1 I have:
private Form2 form2 = new HelpForm();
private void linkLabel_help_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
this.Hide();
form2.Show();
}
and on my second form I have:
private void button_BackToForm1_Click(object sender, EventArgs e)
{
HelpForm form1 = new HelpForm();
this.Hide();
form1.Show();
}
But the problem is if I click the close button (on top right of the window) instead of the GoBack button on the second form, Form1 & Form2 both close in the same time.

How to Focus to another form in C#

I have a program which opens two forms
and I want when I click on Form1
then Focus on Form2.
private void Form1_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2();
frm2.Focus();
}
But this doesn't work, what's wrong in my code?
EDIT:
I found already answered Here by #moguzalp at the comments
First of all that Form2 is never visible.
private void Form1_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2();
frm2.Show();
frm2.Focus();
}
If that Form is visible though with your code, that means you need to get same reference and call Focus() against it.
EDIT:
Then you need to have a reference to that Form.
At some point you created that Form and assigned it to a vairable/field or anything like that.
You need to call Focus or Activate against it.
Example:
Inside Form1 when you create a Form2 instance:
public class Form1 : Form
{
private Form _frm2;
//That code you probably have somewhere. You need to make sure that this Form instance is accessible inside the handler to use it.
public void Stuff() {
_frm2 = new Form2();
_frm2.Show();
}
private void Form1_Click(object sender, EventArgs e)
{
_frm2.Focus(); //or _frm2.Activate();
}
}
If you can have a form opened, try finding it:
using System.Linq;
...
// Do we have any Form2 instances opened?
Form2 frm2 = Application
.OpenForms
.OfType<Form2>()
.LastOrDefault(); // <- If we have many Form2 instances, let's take the last one
// ...No. We have to create and show Form2 instance
if (null == frm2) {
frm2 = new Form2();
frm2.Show();
}
else { // ...Yes. We have to activate it (i.e. bring to front, restore if minimized, focus)
frm2.Activate();
}
If you want to Show your frm2, you should call frm2.Show(); or frm2.ShowDialog();.
Also, before 'Show' call you can set frm2.TopMost = true; if you want this form to be on the top.
So it could be:
private void Form1_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2();
frm2.TopMost = true;
frm2.Show();
}
If you already opened the form elsewhere, then this code will not work as it's a new instance of Form2 and not the one that is opened.
You will have to keep a reference to the form that is opened, and then use Focus or might be better Activate on it.
if the form is opened from within Form1 then:
Add a field for holding current reference of Form2
Save it when showing the form.
Use it when focusing
private Form2 currentForm2;
....
this.currentForm2 = new Form2();
this.currentForm2.Show();
...
...
this.currentForm2.Activate();

Open form2 from two buttons (form1) and matching button that was clicked

I have a little issue, I have form1 in which I got button1 and button2 and I got form2 which I'm able to open with both buttons. Button1 serves as opening form2 and inserting details into SQL DB which can be seen in form1 datagridview. Button2 opens the same form2 but it selects data from form1 and automatically is filling them into textboxes in form2 - it is edit-like.
When I created the button2 (edit button) a problem occured, because form2 didn't knew from which button the was opened.
I thought that everytime I open the form2 I should pass integer so when form2 is loaded it should decide from which button it was opened and act according to that.
Would someone help me solve this thing out?
Thanks
You need to change the constructor of your form 2 to open your form in a different "mode"
Just like this :
Form2.cs
public Form2(bool fromButton2)
{
InitializeComponent();
//Do whatever with that bool
}
And you open your form like this :
Form1.cs
private void button1_Click(object sender, EventArgs e)
{
Form2 frm = new Form2(false);
frm.Show();
}
private void button2_Click(object sender, EventArgs e)
{
Form2 frm = new Form2(true);
frm.Show();
}
Then you can apply your logic with the fromButton2 bool
personally, rather than passing the button or text or a bool I would be explicit and create an enum - pass this to the constructor so you know if you're in editing or display mode. (This covers you if new 'modes' become a requirement) E.g.
public enum EditingType
{
Display,
Editing
}
public class Form2
{
private EditingType _editingType;
public Form2(EditingType editingType)
{
_editingType = editingType;
}
public void DoSomething()
{
if (_editingType == EditingType.Display)
{
// display mode
}
if (_editingType == EditingType.Editing)
{
// editing mode
}
}
}
and to call - Form2 form2 = new Form2(EditingType.Editing);
(passing in editing or display depending on which button click you're handling)
You should create a) a new constructor, which takes button reference ( better name, or whatever You can put into their unused property "Tag" to identify them )
or b ) a public method, which You call before opening the form ( but after instantiating it ) or c) a property in form2, which can take anything You would decide to use as "thing to diffentiate.
Ok ?
Define a new constructor in form2 that takes a string, name of the calling button, as a paremeter and from buttons send the name of the button to the form2 as a parameter and in form2 check the name ButtonName pararmeter for detecting the caller button.

Append text in textbox on another form?

I have 2 forms. On Form2, I have a textbox and a button. When I press the button, I want it to append the text in the textbox to a textbox on Form1. Here's my code:
On Form2:
private void button1_Click(object sender, EventArgs e)
{
frm1.AppendTxt(textBox1.Text);
this.Close();
}
On Form1:
public void AppendTxt(string text)
{
this.body.AppendText(text);
MessageBox.Show(body.Text);
}
For some reason, the text isn't showing up in the textbox on Form1. However, the message box that pops up shows the text I input on Form2.
Try body.Text += " " + text;
Most likely you're changing the textbox inside a hidden copy of Form1, not the instance that's displayed on the screen.
Try passing the Form1 handle to Form2's constructor, and saving it in a class member variable (also called field) to use inside the event handler.
Passing values from form to form.
You can try this. first you can declare a variable that all your forms can access
like this one,
string yourValue;
PS: declare that your class
From form1, you can pass a value to that class.
like this,
YourClass.yourValue = textbox1.text;
Once have a value. pass it to your second form like.
textbox2.text = YourClass.yourValue;
Hope it helps you. :D
You have two form: form1 and form2. Two form is opening. In form2 you have one textbox(txt2) and one button(btn2). In form1 you have one textbox(txt1). When user type something on txt2 and click btn2, the text in txt2 will be append to txt1. This is what you want?
If yes:
In form2, you should create a delegate:
// Declare a delegate
public delegate void GetValue(string value);
// Declare event with delegate
public event GetValue btn2_Clicked;
Then, in form2, you create a function to handle that event: Name of function is the same with name of event you just declare and add prefix "On" in it. Like this:
public void Onbtn2_Clicked(string value)
{
if (btn2_Clicked != null)
{
btn2_Clicked(value);
}
}
After that, in btn2 click event, rise your event just created:
private void btn2_Click(object sender, EventArgs e)
{
Onbtn2_Clicked(txt2.Text);
}
Ok, that is done in form2. Comeback form1 to finish:
I assume form2 is opened when user click a button(btn1) in form1, so in btn1 click event:
private void btn1_Click(object sender, EventArgs e)
{
// Create form2
Form2 frm2 = new Form2();
// Handle btn2 click
frm2.btn2_Clicked += new Form2.GetValue(frm2_btn2_Clicked);
// Show form2
frm2.Show();
}
void frm2_btn2_Clicked(string value)
{
// When btn2 is clicked, the text in txt2 will be assign to txt1
txt1.Text = value;
}
And the text will be assign to txt1 in form1
I think you have to create getters and setters for your textbox so it will be exposed as part of your form class and you can access it as a form object
first forn
public string sometext
{
get { return sometext.Text; }
set { sometext.Text = value; }
}
second form
Form1 form= new Form1();
form.sometext = "some name";
here is another short solution i found
In Form1 initiate form 2
Form2 form2 = new Form2();
form2.Owner = (Form)this;
form2.Show();
and in Form2's
this.Owner.Controls.Find("TextBox1",true).First().Text="Hi!!!!"
How about just change the txtBox in the Form2.designer.cs from private to public?
private System.Windows.Forms.TextBox textBox1;
to
public System.Windows.Forms.TextBox textBox1;
This way you can just send it like this in Form2:
Form1 frm1 = new Form1();
private void button1_Click (object sender, EventArgs e)
frm1.textBox1.AppendText(textBox2);
textBox2 being the one where you enter your text in Form2

Going from 2nd form back to the first form in the same instance

I have a program that consists of two winforms and three classes, one of which is static. My first form does some work and has a button that opens the second form. When the second form opens, the first one closes via this.Visible = false.
I have a button on the second form that I want to take me back to same instance of the first form so that I can input more information if needed. Any new information would have to be added to the original information so that I can go back to the second form.
Is there a way to do this? I tried instantiating a new form but of course the previous values were gone.
Here is the code for my first form to open the second:
//event handler to call Daily Summary form
private void btnDailySummary_Click(object sender, EventArgs e)
{
DailySummaryForm form2 = new DailySummaryForm();
this.Visible = false;
form2.Show();
}
Here is the code for my second form to reopen the first:
private void btnRtnToOrderMenu_Click(object sender, EventArgs e)
{
//closes Daily Summary form
this.Close();
}
I tried doing "OrderForm.Visibile = true" but of course without instantiating a new instance that doesn't work. I'm at a loss.
When you create Form2, you can pass in a reference to Form1 in the constructor.
So Form2 constructor:
public Form2(Form form1)
{
//Do stuff with form1, such as store reference to use later
}
And then when you create Form2 in Form1, you can do this:
Form2 form2 = new Form2(this);
There are a lot of ways, but here is one that I like the design of:
private void btnDailySummary_Click(object sender, EventArgs e)
{
DailySummaryForm form2 = new DailySummaryForm();
this.Visible = false;
form2.Show();
form2.Closing += (sender, args) =>
{
this.Show();
}
}
(Note: this is all offhand; may need minor syntactical fixes to compile).
This way form2 doesn't need to know about form1 at all, it just knows that someone else wants to run some code when it gets closed. Form1 on the other hand is able to tell form2, open me when you're done. The most common/trivial example is to just pass the instance of Form1 around (as another answerer has already proposed) but this exposes everything about Form1 to Form2, allowing it to do a lot of things that you might not want. It also increases the coupling between the two forms (meaning you can't use one without the other).
Does Form2 need to keep the old information when you go back to form1? If so, then you need to make sure that, when you reopen Form2, you are not creating a new object.
DailySummaryForm form2;
private void btnDailySummary_Click(object sender, EventArgs e)
{
if(form2 == null) //Check for null ...
form2 = new DailySummaryForm(); //..and create new Form2 if it is null.
this.Visible = false;
form2.Show();
}
This way, when you re-open Form2 after the first time, the old information will still be there and then you could simply add the new information.
At this point, it'd be best to create some sort of event in Form1 that, when raised, causes something (such as an update) to happen in Form2.
Otherwise, if you do not need to keep the old information, feel free to dispose of Form2 when you switch back to Form1 and simply pass the new version of the information from Form1 into Form2 using a constructor like others have suggested.

Categories

Resources