Get the value of a textbox100 of Form2 to Form1 - c#

I want to hide a button when the DateTime.Now = a input date by user. The textbox100 is in the Form2 and is already public, but I know something else is missing, because I get the error: "The name 'textBox100' does not exist in the current context."
Thank you.
public void Form1_Load(object sender, EventArgs e)
{
var dateTimeStr = textBox100.Text;
var user_time = DateTime.Parse(dateTimeStr);
var time_now = DateTime.Now;
if (time_now >= user_time)
{
button1.Visible = false;
}
}

You need to improve your communication between the forms. See the accepted answer in this question.
Adapted to your code:
using ( var form = new Form2() )
{
var dateTimeStr = form.textBox100.Text;
var user_time = DateTime.Parse(dateTimeStr);
var time_now = DateTime.Now;
if (time_now >= user_time)
{
button1.Visible = false;
}
}
If you need to wait before taking the value of the TextBox, that is, wait for the user to type in the input, then you can write:
string dateTimeStr;
using ( var form = new Form2() )
{
form.submitButton.OnMouseUp += (source, e) =>
{
dateTimeStr = form.textBox100.Text;
};
}
Assuming you have a submission button somewhere in your form.

even if it's public, it still belongs to the class Form2
var dateTimeStr = Form2.textBox100.Text;

You cant get the text of textbox100 if Form2 not instantiated an having a reference in Form1. Then use the line from UnLoCo. Of course its has to be public in Form2

Related

The FormClosing event seems to run after a different Form is started

I did a lot of research about this problem and tried methods but none of them worked. First I will show you what is in my application and what I want it to be with some pictures.
Picture 1
As you can see in the first picture, I open new childForms using the buttons on the main form. One of them is the form named "Price". This form saves the prices entered by the user to the json file. I do the saving process in the FormClosing event. (Yes i know but I don't want to use the "Save" button.)
Picture 2
As you can see in the second picture, the "Result" form did some mathematical operations by reading the values entered by the user in the "Price" form over json.
Now let's come to the problem, I open the "Price" form, change the values and press the result button. Results are coming, everything is great! But the results are not correct because when the "Result" Form was run it didn't wait for the current values to be saved in json. So it didn't wait for the "Price" form to close (i.e. it didn't wait for the Price.FormClosing event to complete).
To avoid this error, I open the results form after opening a different form, but this is amateurish.
I hope I was able to explain my problem clearly.
Thanks in advance for your answers and thoughts.
Code to Write Current Values to JSON File:
private void ProductPricesForm_FormClosing(object sender, FormClosingEventArgs e)
{
string jsonString = JSONOperations.getItemsAsString(products);
File.WriteAllText(JSONOperations.productsJSONPath, jsonString);
}
Code to Read JSON File:
private static void getItems()
{
using (StreamReader r = new StreamReader(JSONOperations.productsJSONPath))
{
string json = r.ReadToEnd();
products = JSONOperations.getItemsAsClass<Product>(json);
}
}
Form Opening Code:
private void buttonResult_Click(object sender, EventArgs e)
{
openChildForm(new ResultForm());
}
private void buttonProductPrices_Click(object sender, EventArgs e)
{
openChildForm(new ProductPricesForm());
}
private Form activeForm;
private void openChildForm(Form childForm)
{
if (activeForm == null)
{
startChildForm(childForm);
}
else
{
if (String.Equals(activeForm.Name, childForm.Name))
{
return;
}
else if (!String.Equals(activeForm.Name, childForm.Name))
{
activeForm.Close();
startChildForm(childForm);
}
}
}
private void startChildForm(Form childForm)
{
childForm.TopLevel = false;
childForm.FormBorderStyle = FormBorderStyle.None;
childForm.Dock = DockStyle.Fill;
panelChildForm.Controls.Add(childForm);
panelChildForm.Tag = childForm;
childForm.BringToFront();
childForm.Show();
activeForm = childForm;
}
You can simply Hide the dialog instead of close.
First, create your childs types:
private enum FormType
{
Result = 0,
Products = 1,
//...
}
An a method to create each form:
private Form CreateChildForm(FormType formType)
{
switch (formType)
{
case FormType.Result:
return new ResultForm();
case FormType.Products:
return new ProductPricesForm();
default:
return null;
}
}
Now, in your form, add this fields:
private int _activeChildIndex = -1;
private readonly Form[] _childsForms = new Form[Enum.GetNames(typeof(FormType)).Length];
_childsForms will store each type of ChildWindow that you create. _activeChildIndex indicates the _childsForms which is active now.
private void ShowChildWindow(FormType formType)
{
var index = (int)formType;
if (this._activeChildIndex == index)
{
return;
}
if (this._activeChildIndex >= 0)
{
var activeChild = this._childsForms[this._activeChildIndex];
// TODO: Hide form
this.OnHideForm(this._activeChildIndex);
}
this._activeChildIndex = index;
if (this._childsForms[index] != null)
{
// TODO: Reset to default (or leave with last state, as you prefer)
// TODO: And show
}
else
{
// TODO: Create child form
var childForm = this.CreateChildForm(formType);
if (childForm != null)
{
this._childsForms[index] = childForm;
}
}
this.OnShowForm(this._activeChildIndex);
}
This method create a child form if not exists and show when was previously created.
In your ProductsForm, add a method to get the JSON:
public string GetProductsJson()
{
return JSONOperations.getItemsAsString(products);
}
Now, you can use OnShowForm in this way:
private void OnShowForm(int index)
{
var formType = (FormType)index;
if (formType == FormType.Result)
{
var productsForm = this._childsForms[(int)FormType.Products];
if (productsForm != null)
{
var json = productsForm.GetProductsJson();
}
}
}
When you activate your result form, search your products form. If was previously created, get the Json. You don't need save to file the json to use here. Save it if you need for other reason.
Do some changes in FormClosing:
private void ProductPricesForm_FormClosing(object sender, FormClosingEventArgs e)
{
// Do this if you need
string jsonString = GetProductsJson();
File.WriteAllText(JSONOperations.productsJSONPath, jsonString);
// TODO: You need a flag to know when are you closing the app.
// In that case, don't cancel
e.Cancel = true;
}
UPDATE
I don't like this solution but may be that you are waiting for:
First, add a method to get the Json in your Product form:
public string GetJson()
{
return JSONOperations.getItemsAsString(products);
}
And a field in your main form:
private string _productsJson;
Instead of a file, use this string. You also can save to file if you need for other purposes.
Change this other method:
private void buttonProductPrices_Click(object sender, EventArgs e)
{
var form = new ProductPricesForm();
form.FormClosing += (sender2, e2) => this.OnProductsPrices(form.GetJson());
openChildForm(form);
}
It do the same as you was doing and also get the closing event to get the Json and invoke to OnProductsPrices with that string.
private void OnProductsPrices(string json)
{
if (_productsJson != json)
{
_productsJson = json;
var form = activeForm as ResultForm;
if (form != null)
{
form.DoSomethingWithTheJson(json);
}
}
}
If the Json doesn't change, you don't need to do anything. When it's changed, you update your _productsJson and check if current form is ResultForm. In this case, you load the Json or do whatever you do with the Json in that Form.
Also, you must use _productsJson when you create the ResultForm, like know, that I suppose you get from file. In this way, you use the json always when you create ResultForm or later, when the ProductsForm is closed.
private void buttonResult_Click(object sender, EventArgs e)
{
var form = new ResultForm();
openChildForm(form);
if (!string.IsNullOrEmpty(_productsJson))
form.DoSomethingWithTheJson(_productsJson);
// Or do the same in the constructor and manage inside the form, calling to DoSomethingWithTheJson
//var form = new ResultForm(_productsJson);
}

Using variables in primary Form from secondary From

I am having issues transfering data points from one form to another. I have made sure that the button inside of addTagsForm has a public modifier.
I've looked at multiple solutions of using data values from one form to another and I must be missing something from them.
Here is what I have in Form1:
//Inside Form1
XMLDocGen.PLCData PLC = new XMLDocGen.PLCData();
List<XMLDocGen.TagData> tags = new List<XMLDocGen.TagData>();
AddTagsForm addTagsForm = new AddTagsForm();
addMoreTagsSelected = addTagsForm.addMoreTagsEnabled;
if(addMoreTagsSelected)
{
for(int i= 0; i < 8; i++)
tags.Add(new XMLDocGen.TagData(addTagsForm.addTags[i], addTagsForm.addDataTypes[i], addTagsForm.addElemSizes[i], addTagsForm.addElemCounts[i]));
}
Here is what is inside of addTagsForm
public void button1_Click(object sender, EventArgs e)
{
addMoreTagsEnabled = true;
var tagNames = new List<TextBox>() { tagNameBoxAMT1, tagNameBoxAMT2, tagNameBoxAMT3, tagNameBoxAMT4, tagNameBoxAMT5, tagNameBoxAMT6, tagNameBoxAMT7, tagNameBoxAMT8 };
var dataTypes = new List<ComboBox>() { dataTypeBoxAMT1, dataTypeBoxAMT2, dataTypeBoxAMT3, dataTypeBoxAMT4, dataTypeBoxAMT5, dataTypeBoxAMT6, dataTypeBoxAMT7, dataTypeBoxAMT1 };
var elemSizes = new List<TextBox>() { elemSizeBoxAMT1, elemSizeBoxAMT2, elemSizeBoxAMT3, elemSizeBoxAMT4, elemSizeBoxAMT5, elemSizeBoxAMT6, elemSizeBoxAMT7, elemSizeBoxAMT8 };
var elemCounts = new List<TextBox>() { elemCountBoxAMT1, elemCountBoxAMT2, elemCountBoxAMT3, elemCountBoxAMT4, elemCountBoxAMT5, elemCountBoxAMT6, elemCountBoxAMT7, elemCountBoxAMT8 };
for (int i = 0; i < 8; i++)
{
addTags.Add(tagNames[i].Text);
addDataTypes.Add(dataTypes[i].Text);
addElemSizes.Add(elemSizes[i].Text);
addElemCounts.Add(elemCounts[i].Text);
}
this.Hide();
}
I have checked to make sure each list is populated correctly and they are. As well as the Lists being public. The problem is trying to grab these values from Form1. There has to be something simple that I'm missing! Thanks for the help!
With the reference of your comment i've generated an idea for you. By writing a simple public Action in your Second form Form2 you can achieve your goal. Below i'm showing an example:
Declare a public Action in your Form2 global scope with your desired collection type, like this way:
public Action<List<TextBox>, List<ComboBox>> actGetCollection;
Keep a method with some of your desired collection type parameter in your Form1 like this way:
private void GetCollectionItems(List<TextBox> addTags, List<ComboBox> addDataTypes)
{
//you will get your list items here and do whatever you want with these
}
In your Form1 from where your second form will open bind your GetCollectionItems() method with your Action in Form2 (assuming you do this in a button's click event) like this way:
private void button1_Click(object sender, EventArgs e)
{
//create an instance of your Form2 Form
Form2 obj = new Form2();
//bind your function with the action
obj.actGetCollection = GetCollectionItems;
//then call your Form2's ShowDialog() method to show the form
obj.ShowDialog();
//now your Form2 is opended
}
Now in your Form2's button_click event do this:
public void button1_Click(object sender, EventArgs e)
{
addMoreTagsEnabled = true;
var tagNames = new List<TextBox>() { tagNameBoxAMT1, tagNameBoxAMT2, tagNameBoxAMT3, tagNameBoxAMT4, tagNameBoxAMT5, tagNameBoxAMT6, tagNameBoxAMT7, tagNameBoxAMT8 };
var dataTypes = new List<ComboBox>() { dataTypeBoxAMT1, dataTypeBoxAMT2, dataTypeBoxAMT3, dataTypeBoxAMT4, dataTypeBoxAMT5, dataTypeBoxAMT6, dataTypeBoxAMT7, dataTypeBoxAMT1 };
var elemSizes = new List<TextBox>() { elemSizeBoxAMT1, elemSizeBoxAMT2, elemSizeBoxAMT3, elemSizeBoxAMT4, elemSizeBoxAMT5, elemSizeBoxAMT6, elemSizeBoxAMT7, elemSizeBoxAMT8 };
var elemCounts = new List<TextBox>() { elemCountBoxAMT1, elemCountBoxAMT2, elemCountBoxAMT3, elemCountBoxAMT4, elemCountBoxAMT5, elemCountBoxAMT6, elemCountBoxAMT7, elemCountBoxAMT8 };
for (int i = 0; i < 8; i++)
{
addTags.Add(tagNames[i].Text);
addDataTypes.Add(dataTypes[i].Text);
addElemSizes.Add(elemSizes[i].Text);
addElemCounts.Add(elemCounts[i].Text);
}
//call the action
if(actGetCollection != null)
actGetCollection(addTags, addDataTypes);
this.Hide();
}
When your Form2 wil disappear your code will get back to your Form1's event from where you're called your Form2. Now in your GetCollectionItems() you've the collection items that you're wanted.
You can set stuff in your second form from your first:
class Form1
{
...
public void OnButtonPress()
{
var anotherForm = new Form2();
anotherForm.AList = mylist;
anotherForm.BList = myBList;
anotherForm.ShowDialog();
}
}
Alternatively, you could create a class that encapsulates everything you want to pass between the two and so only pass on thing. If it's mandatory I would put it in Form2's constructor:
public Form2(MyImportantStuff stuff)

Call event on first form when second form closes

I have two forms, I open and showdialog the second form like this:
Recieving_Stock_Form f = new Recieving_Stock_Form();
f.Username = Username;
f.Role = Role;
f.Date = monthCalendar1.SelectionStart.ToString(#"yyyy\/MM\/dd");
f.ShowDialog();
Now when I close the second form I want to trigger an event on the first form
E.G
void txtStockCount_TextChanged(object sender, EventArgs e)
Any ideas where I can look up about this or how to do it?
Thanks
in Form1, assuming that your code is this
Recieving_Stock_Form f = new Recieving_Stock_Form();
You can add the code
f.Form_Closing += ExampleHandler;
ExampleHandler(object sender, FormClosingEventArgs e)
{
//Do stuff
}
I'd rather not had cheated with the form; instead, I suggest assigning the value from Recieving_Stock_Form to txtStockCount:
using (Recieving_Stock_Form f = new Recieving_Stock_Form()) {
f.Username = Username;
f.Role = Role;
f.Date = monthCalendar1.SelectionStart.ToString(#"yyyy\/MM\/dd");
// == DialogResult.OK - let user have a chance to cancel his/her input
if (f.ShowDialog() == DialogResult.OK) {
//TODO: put the right property here
txtStockCount.Text = f.StockCount.ToString();
}
}
The ShowDialog is modal so it will block executiong, so when you close it, the next thing is executed.
You can do this:
Recieving_Stock_Form f = new Recieving_Stock_Form();
f.Username = Username;
f.Role = Role;
f.Date = monthCalendar1.SelectionStart.ToString(#"yyyy\/MM\/dd");
f.ShowDialog();
// it will continue here when the form is closed.
txtStockCount_TextChanged(this, EventArgs.Empty); // or assign the variable directly.
There is two events that you can handle - FormClosed and FormClosing, depending on your decision.
f.FormClosed += f_FormClosed;
private void f_FormClosed(object sender, FormClosedEventArgs e)
{
//Call your function or do whatever you want
}

Getting error in retrieving input text from text box to the other form

I have a login form "frmLog()" which has text box for username and password, now I want to get the input text from username text box. Please see the code below and don't be confuse I am using mysql database so the other syntax code are not important.
This is the Login form "frmLog()"
private void button1_Click(object sender, EventArgs e)
{
ApareceCrudLib a = new ApareceCrudLib("localhost", "root", "", "cashieringdb");
string user = txtLogin.Text;
string pass = txtPassword.Text;
string query = "SELECT * FROM register WHERE username='" + user + "' AND password=MD5('" + pass + "')";
int result = a.Count(query);
if (result == 1)
{
frmMain main = new frmMain();
main.ShowDialog();
this.Dispose();
}
else
{
MessageBox.Show("Login Failed! Try Again");
txtLogin.Text = "";
txtPassword.Text = "";
}
}
This is the other form where I want to retrieve the code "frmMain()". Please see the public void dataLog() that is the part of code that I attempt to get the input value from frmLog.
private void frmMain_Load(object sender, EventArgs e)
{
a = new ApareceCrudLib("localhost", "root", "", "cashieringdb");
loadDataGridView_Main();
dataLog();
}
public void loadDataGridView_Main()
{
dgvMain.Rows.Clear();
List<string>[] detailList = a.mysqlSelect("Select * From sales");
for (int i = 0; i < detailList.Length; i++)
{
dgvMain.Rows.Add(detailList[i][0], detailList[i][1], detailList[i][2], detailList[i][3]);
}
}
public void dataLog()
{
frmLog kk = new frmLog();
txtLog.Text= kk.txtLogin.ToString();
}
This is the wrong result
The result must be the username from frmLog() example "client123". What do you think is wrong here?
kk.txtLogin.ToString(), returns a string that represents the current object. In this case your current object is TextBox.
Instead display the TextBox, you should show the TextBox's value.
Change that code to:
kk.txtLogin.Text;
UPDATE
If you want to display the txtLogin value from frmLog in frmMain, you can declare static variable in frmLog that store the txtLogin value.
in frmLog:
public static String LOGIN_USER = "";
Then in button1_Click:
if (result == 1)
{
LOGIN_USER = txtLogin.Text;
frmMain main = new frmMain();
main.ShowDialog();
this.Dispose();
}
in frmMain_Load:
public void dataLog()
{
txtLog.Text= frmLog.LOGIN_USER;
}
In your datalog() Methode is the first error.
Replace:txtLog.Text= kk.txtLogin.ToString();
With:txtLog.Text= kk.txtLogin.Text;
In:
public void dataLog()
{
frmLog kk = new frmLog();
txtLog.Text= kk.txtLogin.ToString();
}
You create a new frmlog object without showing it, so the textbox is empty. You should retrieve the text from the text box after the user input.
It is so because you are trying to read data from a new instance of your frmLog();
In you frmMain, do not write this :
frmLog kk = new frmLog();
instead create a public reference in your form class
public frmLog kk;
and then, In your frmLog,
frmMain main = new frmMain();
main.kk=this;
main.ShowDialog();
this will create a reference to your first form in second form.

NullReferenceException sending input to a TextBox

I'm trying to send a string from form2 to form3 to pre-load the form with info. I call a method on form3 accepting the string which starts a linq query to set the controls on the form. I get a NullReferenceException was unhandled in the first
foreach on recipeNameTextBox.Text = a.RecipeName;
I can see that the query ran and the info is in a.RecipName. I think I might be getting this error because the control hasn't been drawn yet. Any Ideas how to get around this? Form2 code is here:
private void updateButton_Click(object sender, EventArgs e)
{
Form3 Frm3 = new Form3();
Frm3.Show();
this.Hide();
Frm3.takeInputFromForm2(recipeLabel.Text);
}
form3 code here:
public void takeInputFromForm2(string incommingUpdateRecipe)
{
Query updateRecipe = new Query();
IEnumerable<Recipe> newrecipe = updateRecipe.getRecipeInfo(incommingUpdateRecipe);
foreach (var a in newrecipe)
{
recipeNameTextBox.Text = a.RecipeName;
nationalityTextBox.Text = a.Nationality;
eventTextBox.Text = a.Event;
sourceTextBox.Text = a.Source;
typeTextBox.Text = a.Type;
ServingsTextBox.Text = a.Servings;
}
foreach (var b in newrecipe)
{
userRatingTextBox.Text = Convert.ToString(b.UserRating);
familyRatingTextBox.Text = Convert.ToString(b.FamilyRating);
healthRatingTextBox.Text = Convert.ToString(b.HealthRating);
easeOfCookingTextBox.Text = Convert.ToString(b.CookingTime);
cookingTimeTextBox.Text = Convert.ToString(b.CookingTime);
}
foreach (var c in newrecipe)
{
ingredientComboBox.Items.Add(c.RecipeIngredient);
}
}
You are probably missing the InitializeComponent in your Form3 constructor.

Categories

Resources