Handling data between multiple Forms - c#

I am working on a program that generates a PDF file. Before the final generation of the file, I want to give the user the option to edit a portion of the file (The title of the graph that is about to be created). I want this to show up in a new form when the user clicks a button to export the PDF. Here is an outline of what I am trying to do...
private void button4_Click(object sender, EventArgs e) // Test PDF Code!
{
Form2 NewPDF = new Form2(chart3.Titles[chart3.Titles.IndexOf("Header")].Text.ToString().Substring(0, chart3.Titles[chart3.Titles.IndexOf("Header")].Text.ToString().Length - 4));
NewPDF.Show();
if (NewPDF.Selected == true)
{
// Create PDF, open save file dialog, etc
}
}
And here is the Form that is being opened by this button click...
public partial class Form2 : Form
{
public bool Selected
{
get;
set;
}
public String GraphName
{
get;
set;
}
public Form2(String FileName)
{
InitializeComponent();
textBox1.Text = FileName;
GraphName = FileName;
Selected = false;
}
public void button1_Click(object sender, EventArgs e)
{
GraphName = textBox1.Text;
this.Selected = true; // After the button is selected I want the code written above to continue execution, however it does not!
}
}
As of now, when I click on the button in Form2, nothing happens, there is something about the communication between the two Forms that I am not understanding!

You should change your Form2.GraphName like below
public String GraphName
{
get { return textBox1.Text }
}
then change your new Form2 creation like below, test it since I haven't run this through VS, but should work :)
private void button4_Click(object sender, EventArgs e) // Test PDF Code!
{
// why on earth were you doing .Text.ToString()? it's already string...
Form2 NewPDF = new Form2(chart3.Titles[chart3.Titles.IndexOf("Header")].Text.Substring(0, chart3.Titles[chart3.Titles.IndexOf("Header")].Text.Length - 4));
// show as a dialog form, so it will wait for it to exit, and set this form as parent
NewPDF.ShowDialog(this);
if (NewPDF.Selected == true)
{
// get the name from the other form
string fileName = NewPDF.GraphName;
// Create PDF, open save file dialog, etc
}
}

The answer to your problem is quite simple.
NewPDF.Show();
Show() does not pause execution of the calling form. Therefore, the check underneath that that verifies the Selected property if true will never execute properly, since that check is reached and verified just as the form starts appearing. ShowDialog() does pause execution and waits for the called form to close.
That aside; I would recommend one of two other ways to communicate between forms;
Use a global variable. Declare a variable holding the graph's name somewhere in a public module. Call the dialog that asks the user to input a name with ShowDialog(), since that pauses execution of the calling form until the called form returns a result.
if(Form.ShowDialog() == DialogResult.OK) {
// Save pdf, using title in global variable
}
Make sure to set the DialogResult in the called form before Close()-ing it.
Pass an instance variable of the calling form to the called name-input form to the constructor and save it. That way, if you expose the graph name property as a public property, you should be able to access it from the called form in the code that closes the form, which is your:
public void button1_Click(object sender, EventArgs e)
{
callingFormInstance.GraphNameProperty = textBox1.Text;
Close();
}
Hope that helps. Cheers!

Related

How pass information between forms involving listView item being changed?

I have file manager program that displays folder in a treeView on the left hand side of a form (frmMain) and files in listView on the left side. I want to be able to select a file (item) from the listView then display the file name in a text on another form with the label = 'Enter a file name.' then rename the file with that new name.
Code from the second form.
public frmRename(string oFile)
{
InitializeComponent();
textBox1.Text = oFile;
}
private void bntOK_Click(object sender, EventArgs e)
{
string nFileName;
nFileName = textBox1.Text;
frmMain fm = new frmMain();
fm.re_nameFile(nFileName);
}
This code runs without any errors; however, when uncommented that is presently commented I get error 'Value of zero is not a valid for index'. I know that this error has talked about a lot; however, I am concern with a different aspect of this error. If I use a line of in private function I don't get this error; whereas, if I use it public function I do. First of all I want to understand why this happens? Second can you tell me how to fix the problem?
So in frmMain you create a new frmRename and in frmRename you create a new frmMain. Bad idea. The new frmMain knows nothing about the original frmMain (including its populated listView).
Solution: in frmMain.bntRename_Click call
rename.ShowDialog();
newFileName = rename.nFileName;
do whatever you want to do with the new name and in frmRename define
public string nFileName {get; private set;}
and further change
private void bntOK_Click(object sender, EventArgs e)
{
nFileName = textBox1.Text;
Close();
}

C# Game Menu Form ( Username, Start, Exit )

i'm new to the programming went through few tutorials and sample projects and then started to create my own text based adventure game with some UI.
So what i'd like to achieve with the beginning of my project is, when user launches exe, i'd like to greet them with a username input screen with Start and Exit buttons and then close that form, launch a new form which i'll put in the game's main interface.
So, when i click the "Start" Button, it'll read the username from the textbox, save it to a string, close the form and launch a new form with also using the name screen in the game's main interface.
My question is, How can i link the start button from the below code to a new Form, also closing the current AUJFM_Login form, which will also be able to read the string username.
I have tried few things but after a few attempts, i just left it with the button functions. It's not much but here is the basics of it:
The Greeting screen will be called AUJFM_Login, and the main interface will be called AUJFM.
namespace AUJFM
{
public partial class AUJFM_Login : Form
{
public AUJFM_Login()
{
InitializeComponent();
}
private void btnStart_Click(object sender, EventArgs e)
{
string UserName = nameBox.Text;
}
private void btnExit_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
You can try the code below for the “Start” button click. I added a method to check the user name as it seems like sending an invalid user name to the next form is simply a waste of time. You will have to adjust this method to check for the valid users. Hope this is what you are looking for.
private void btnStart_Click(object sender, EventArgs e) {
string userName = nameBox.Text;
if (ValidUserName(userName)) {
SecondForm nextForm = new SecondForm(userName);
nextForm.Show();
this.Hide();
} else {
// user name not valid
}
}
private bool ValidUserName(String userName) {
// logic to check if user name is valid
return true;
}
Then in the second form constructor, change the signature to accept the user name string.
public SecondForm(string userName) {
InitializeComponent();
textBox1.Text = userName;
}
If you have a form for the main window (Let's call it MainForm),
you can do:
MainForm mainForm = new MainForm();
mainForm.Show();
The main window would then appear.
To close the login form, you could do
this.Hide();
Since closing the form from which the application runs would close the entire application.

How to add a text to CheckBox from form2 to form 1 (C#)

So, I've just started learning C# and I have been looking on tutorials in YouTube but in Console Applications.
I have now made my first WFA and I'm trying to create a Calendar where you can add different times with different texts so you stay informed for example a upcoming test.
So far I've come this far: It's in Swedish
And I've also connected the "Lägg Till" (Add in English) to another form called laggTill
Connection in codeform -
laggTill lgtl = new laggTill ();
lgtl.Show ();
Form2 called laggTill looks like:
Also in Swedish
So my question is, how can I by pressing the "Spara" button (Save in English) put the text from the TextBox in laggTill form to the CheckBox in the "Kommande datum:" CheckBox?
Create public properties in Form2, in the example below you can see how to access them.
you did not asked that, but sometimes you dont want to update Form1 (for example the user pressed on cancel button) - use the DialogResult value of Form 2 in order to determine if there is a need to update Form1, in the example DialogResult is DialogResult.OK but it could be also DialogResult.Cancel.
user presses "Spara" button on Form2:
public string valueToForm1 { get; set; } //public properties to access from form1
public DateTime value2ToForm1 { get; set; }
private void button1_Click(object sender, EventArgs e)
{
this.valueToForm1 = "SomeValue";
this.value2ToForm1 = dateTimePicker1.Value;
this.DialogResult = DialogResult.OK;
this.Close();
}
calling Form2 from Form1:
private void button1_Click(object sender, EventArgs e)
{
using (var form = new Form2())
{
var result = form.ShowDialog();
if (result == DialogResult.OK)
{
//values preserved after close
string val = form.valueToForm1;
DateTime dateValue = form.value2ToForm1;
//for example
this.txtValueFromForm2.Text = val;
this.dateTimePicker1.Value = dateValue;
}
}
}
on another button on Form2 (lets say cancel button) you can do that piece of code, if there is a case that you dont want to update Form1:
private void button2_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
this.Close();
}

How to close form

Ok, so a Windows Forms class, WindowSettings, and the form has a "Cancel"-button. When the user clicks the button, the dialog DialogSettingsCancel will pop-up up and ask the user if he is sure he wants to perform the action. The dialog has 2 buttons, a "Yes"-button and a "No"-button. If the user clicks the "Yes"-button, I want both DialogSettingsCancel and WindowSettings to be closed.
My button_Click event handler in DialogSettingsCancel:
private void button1_Click(object sender, EventArgs e)
{
//Code to trigger when the "Yes"-button is pressed.
WindowSettings settings = new WindowSettings();
this.Close();
settings.Close();
}
When I run my application, and go to the settings form, and click the "Cancel"-button, and then click the "Yes"-button, only DialogSettingsCancel closes without closing WindowSettings.
Why won't it work?
I've also tried changing
this.Close();
settings.Close();
to
settings.Close();
this.Close();
But still the same result.
You need the actual instance of the WindowSettings that's open, not a new one.
Currently, you are creating a new instance of WindowSettings and calling Close on that. That doesn't do anything because that new instance never has been shown.
Instead, when showing DialogSettingsCancel set the current instance of WindowSettings as the parent.
Something like this:
In WindowSettings:
private void showDialogSettings_Click(object sender, EventArgs e)
{
var dialogSettingsCancel = new DialogSettingsCancel();
dialogSettingsCancel.OwningWindowSettings = this;
dialogSettingsCancel.Show();
}
In DialogSettingsCancel:
public WindowSettings OwningWindowSettings { get; set; }
private void button1_Click(object sender, EventArgs e)
{
this.Close();
if(OwningWindowSettings != null)
OwningWindowSettings.Close();
}
This approach takes into account, that a DialogSettingsCancel could potentially be opened without a WindowsSettings as parent.
If the two are always connected, you should instead use a constructor parameter:
In WindowSettings:
private void showDialogSettings_Click(object sender, EventArgs e)
{
var dialogSettingsCancel = new DialogSettingsCancel(this);
dialogSettingsCancel.Show();
}
In DialogSettingsCancel:
WindowSettings _owningWindowSettings;
public DialogSettingsCancel(WindowSettings owningWindowSettings)
{
if(owningWindowSettings == null)
throw new ArgumentNullException("owningWindowSettings");
_owningWindowSettings = owningWindowSettings;
}
private void button1_Click(object sender, EventArgs e)
{
this.Close();
_owningWindowSettings.Close();
}
You can also close the application:
Application.Exit();
It will end the processes.
new WindowSettings();
You just closed a brand new instance of the form that wasn't visible in the first place.
You need to close the original instance of the form by accepting it as a constructor parameter and storing it in a field.
Why not use the DialogResult method to close the form?
if(DialogSettingsCancel.ShowDialog() == DialogResult.Yes)
{
//this will close the form but will keep application open if your
//application type is "console" in the properties of the project
this.Close();
}
For this to work however you will need to do it inside your "WindowSettings" form while you call the DialogSettingsCancel form. Much the same way you would call the OpenFileDialog, or any other Dialog form.
Your closing your instance of the settings window right after you create it. You need to display the settings window first then wait for a dialog result. If it comes back as canceled then close the window. For Example:
private void button1_Click(object sender, EventArgs e)
{
Settings newSettingsWindow = new Settings();
if (newSettingsWindow.ShowDialog() == DialogResult.Cancel)
{
newSettingsWindow.Close();
}
}
send the WindowSettings as the parameter of the constructor of the DialogSettingsCancel and then on the button1_Click when yes is pressed call the close method of both of them.
public class DialogSettingsCancel
{
WindowSettings parent;
public DialogSettingsCancel(WindowSettings settings)
{
this.parent = settings;
}
private void button1_Click(object sender, EventArgs e)
{
//Code to trigger when the "Yes"-button is pressed.
this.parent.Close();
this.Close();
}
}
for example, if you want to close a windows form when an action is performed there are two methods to do it
1.To close it directly
Form1 f=new Form1();
f.close(); //u can use below comment also
//this.close();
2.We can also hide form without closing it
private void button1_Click(object sender, EventArgs e)
{
Form1 f1 = new Form1();
Form2 f2 = new Form2();
int flag = 0;
string u, p;
u = textBox1.Text;
p = textBox2.Text;
if(u=="username" && p=="pasword")
{
flag = 1;
}
else
{
MessageBox.Show("enter correct details");
}
if(flag==1)
{
f2.Show();
this.Hide();
}
}
There are different methods to open or close winform.
Form.Close() is one method in closing a winform.
When 'Form.Close()' execute , all resources created in that form are destroyed.
Resources means control and all its child controls (labels , buttons) , forms etc.
Some other methods to close winform
Form.Hide()
Application.Exit()
Some methods to Open/Start a form
Form.Show()
Form.ShowDialog()
Form.TopMost()
All of them act differently , Explore them !

C# change textbox text on a modal form from an another form

I'm trying to change a text on a TextBox on a modal main form by clicking on a button from an another active form, need help.
Main form *Modal mode
public void changetext(){
textbox1.text = textnew;
}
form2 *active form
private void btnChange_Click(object sender, EventArgs e)
{
mainform form1 = new mainform;
public String textnew = "NEW"
form1.changetext();
this.close
}
Ive tired to use this code but it gives me the error of : Invoke or BeginInvoke cannot be called on a control until the window handle has been created.:
public void LabelWrite(string value)
{
if (InvokeRequired)
Invoke(new LabelWriteDelegate(LabelWrite), value);
else
{
textBox1.Text = value;
}
}
delegate void LabelWriteDelegate(string value);
i think there's a logic issue. If i understand your requirement, you have a main form which contains a search textbox. When the user launch a serach, you open a modal form where all possible results are displayed. The user selects the value he wants and then you get the result in the main form. Is this correct? If so you should do it this way:
Create a public property on the modal form which contains the result.
Either create a public property or create a new constructor on the modal form to pass the query.
On the main form, you can access the public properties of the modal form as long as it is not disposed.
For instance:
var result = null;
var modal = new ModalForm(query);
if(modal.ShowDialog() == DialogResult.OK) // This means the user has selected a value
{
result = modal.SelectedResult;
}
modal.Close();
modal.Dispose();
The easiest way is to pass the new text to the modal window.
For example:
Main form Modal mode
public void changetext(String textnew){
textbox1.text = textnew;
}
form2 active form
private void btnChange_Click(object sender, EventArgs e)
{
mainform form1 = new mainform;
form1.changetext("NEW");
this.close
}
If I were you I would also change form names, they are a little bit confusing.
P.S. I still don't get what is this.close is needed for.

Categories