Access variable from another form in Visual Studio with c# - c#

I'm using c# and Visual Studio. I want to access a variable from another form. I've found some things like:
textBox1.Text = form22.textBoxt17.Text;
But I don't want to access a textBox value, I just want to access a variable. I've tried this:
string myVar1 = Form2.myVar2;
But that doesn't work.
Any help?
Update
This is what I've got now:
private string _firstName = string.Empty;
public string firstName
{
get
{
return _firstName ;
}
set
{
if (_firstName != value)
_firstName = value;
}
}
In formLogin (where the variable is located), just below public partial class formLogin : Form
Then, later in code, inside button on click event:
OleDbCommand command2 = new OleDbCommand();
command2.Connection = connection;
command2.CommandText = "select firstName from logindb where username = '" + txtUsername.Text + "' and password = '" + txtPassword.Text + "'";
firstName = command2.ExecuteScalar().ToString();
I write this in formAntonyms (from where I want to access the variable) in formLoad event:
formLogin fli = new formLogin();
lblName.Text = fli.firstName;
The problem with all this is that, when formAntonyms opens, lblName is still empty, instead of showing the users name. What am I doing wrong, I've done all the steps right...

You are on the right path, you should not expose controls or variables directly to client code.
Create a read only property in the form/class you want to read the value from:
//Form2.cs
public string MyVar{get{ return textBoxt17.Text;}}
Then, being form22 the instance variable of your already loaded Form2 form class. Then, from any client code that has a reference to it, you can read the value of the property:
string myVal = frm22.MyVar;
EDIT:
Ok based in your last comment, you have a variable in Florm1 and want to access it from Form2, the principle is the same as the previous example, but instead of exposing a control property you now expose a private variable, and instead of living in Form2 it now lives in Form1:
//Form1.cs
private string _myVar = string.Empty
public string MyVar
{
get
{
return _myVar ;
}
set
{
if(_myVar != value)
_myVar = value;
}
}
The property is now read/write so you can update its value from client code
//From From2, assuming you have an instance of Form1 named form1:
string val = form1.MyVar;
...
form1.MyVar = "any";

First of all it is bad object oriented design to access variables from classes directly. It reduces maintainability and reusability.
Your problems arise, because the functionality of your objects is not clear to you.
You should not think in terms of "I want the value of this variable", but in terms of: "Suppose you have a form22, what properties should such a form have?".
Well, apparently it has a size and a position and lots of others, and apparently your form has some information that it displays, and you think that users of this form want to know the text of the displayed information.
Let's suppose the displayed information is named MyInformation. Be aware, that you can only display a description of the information. This descriptive text is not the information itself.
A proper object oriented design of your form would be
class Form22 : Form
{
public string MyInformationText {get {return ...; }
...
}
Now you are communicating to the users of Form22 that a Form22 has some MyInformation. You also communicated that you are not willing to share this information, only to share a descriptive text of the information. Furthermore users of your form can't change this information.
This gives you a lot of advantages. For instance, suppose you don't want to display the text in a TextBox, but in a ComboBox. Or maybe you don't want to display it at all anymore. The users of the form who wanted a descriptive text of MyInformation don't have to change.
Of course your design could be different if you want users of your form to change the information. Probably that would also mean that you need to change the displayed description of your information. But again: users of your form won't need to know this. Again, this gives you the freedom to change it without users having to change:
public MyInformation SpecialInformation
{
get {return this.mySpecialInformation;}
set
{
this.mySpecialInformation = value;
this.UpdateDisplay(mySpecialInformation);
}
}
It depends on your model if you should still provide a property for the displayed text or not: Should all MyInformation object in the world have the same displayed text, or could it be that the displayed text in form22 might differ from the displayed text of MyInformation in form23? The answer to this influences whether MyInformation should have a function to get the descriptive text, or whether the forms should have a function to get the descriptive text.
These are just examples to show that you should think in: what should my object do? What should users of my object be capable to do with my objects. The more you allow them to do, the less you will be able to change. You will have the greatest flexibility if you supply them with no more information than required. Besides you'll need to test much less functionality.

Related

C# GUI save input text (TextBox) [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I'm pretty new to the C# and while making my first program i'm facing a problem.
So I got 3 windows form (MyForm1; MyForm2 and MyForm3)
MyForm1 has 2 buttons (Available Account & Add a new account)
When i click one of these buttons it opens a new windows form.
In the Add a new Account form I have 2 TextBox (1 for the ID and 1 for the PWD + Button (Save) and i'd like the user to input his ID and PWD and save it so i can re-use it in the Available Account form but i have no clue how to that. I tried different things i saw on YT but nothing seems to works like i would
Thanks for your help <3 (Tell me if you want me to copy/paste some part of the code).
Edit:
Here are the sourcecodes of the mentioned forms.
Form1
Form2
Form3
I deleted all my failed attemps, so they are basics.
From your post it's hard to determine what you're trying to do. So. If you only want to pass values between forms, you could do something like this:
Add new account form:
public static bool AddNewAccount(out int id, out string password)
{
id = 0;
password = "";
AddNewAccountForm f = new AddNewAccountForm();
bool result = (f.ShowModal() == ModalResult.OK);
if(result)
{
id = f.GetId();
password = f.GetPassword();
}
f.Dispose();
return result;
}
and in main form:
int id;
string pass;
if(AddNewAccountForm.AddNewAccount(out id, out pass))
{
//here user clicked OK, so you can save to the database your id and password
}
else
{
//here user clicked Cancel
}
I assumed that there are two buttons on your AddNewAccountForm. One - OK and the other - Cancel. You have to set the modal result for these buttons.
So, how it works?
AddNewAccount method is static method, so you can call it from your main like:
AddNewAccountForm.AddNewAccount()
AddNewAccount method is going to create your form, show it modally and then assign values enetred by user to out parameters.
My code assumes also that your AddAccountForm has methods like:
int GetId()
{
return Convert.ToInt32(idTextBox.Text);
}
string GetPassword()
{
return passwordTextBox.Text;
}
Note that GetId is badly written, I wanted it to be clear. Now that you understand this method, conversion to int should look like that (TryParse is better way to convert string to int):
int GetId()
{
int id;
if(!int.TryParse(idTextBox.Text, out id))
return -1;
else
return id;
}
You can also "group" id and password in some structure. Code would be cleaner. But I don't think you need it now. However, if you are curious you can read about structures here: https://msdn.microsoft.com/en-us/library/aa288471%28v=vs.71%29.aspx?f=255&MSPPError=-2147217396
If you want to store values in database or files:
** Part about good practices and system engeneering **
You should really not save them using AddAccountForm. This class is to create account in your application (just the model) - not to save it. If you want to store these values(id and password) you should pass them to your main form - as I already showed you and then main form should save them - using another class which is responsible for data management. I am not giving any example, because I don't know if you really need it now.
To make your code really reusable, you should keep a strict separation between display (view) and the data.
You didn't mention that you had a database. This lack of mention is a start of this separation. Your problem would be similar if you just have a List of account, or a Dictionary, or maybe a text file containing the items you want to edit in your application.
So let's assume you want to edit a collection of Accounts. You want to be able to add an Account to this collection, or change the data of an existing account in this collection.
This functionality is similar to the functionality of an ICollection<Account>.
So all that Form1 needs to know, is that it holds an ICollection<Account>. Somehow during initialization Form1 loads the Accounts collection. If the operator presses Add, a Form2 opens where he can fill in the required values for a new Account. The operator chooses either OK or Cancel to indicate he want this Account to be added to the collection or not (Using a Save button in the form is not windows standard and a bit unclear, so don't use it).
Add an Account
Code in Form1
private ICollection<Account> existingAccounts;
void OnButtonAdd(object sender, ...)
{
using (var form = new Form2())
{
form. ...// fill any needed values
// show form2 and check if OK or Cancel:
var dlgResult = form.ShowDialog(this);
// only add if OK pressed, otherwise ignore
if (dlgResult == DialogResult.OK)
{
this.existingAccounts.Add(form.Account);
}
}
}
Cond in Form2
In visual studio designer create a Form with a TextBox for the ID and a textbox for the password (give it password properties, so it displays *****)
Add an OK and a Cancel button. Give the DialogResult property of these buttons the proper OK and Cancel value.
Finally add one property to get the typed values:
public Account Account
{
get
{ // extract the values from the display
return new Account()
{
Id = this.TextBoxId.Text,
Pwd = this.TextBoxPwd.Text,
};
}
}
Edit existing Account
You also have a button to edit an existing account. Do you only want to edit the last Added account, or do you want to be able to edit any existing account?
In the latter case you'll have to make something that displays all existing account where operators can select one of them. Probably using a DataGridView, or a BindingSource. You'll probably end up with a function like:
Account GetSelectedAccount() {...}
The Form to edit an existing Account is similar to the form to create a new account. You should really consider using the same form for it.
public Account Account
{
get
{ // extract the values from the display
return new Account()
{
Id = this.TextBoxId.Text,
Pwd = this.TextBoxPwd.Text,
};
}
set
{
this.TextBoxId.Text = value.Id;
this.TextBoxPwd.Text = value.Pwd;
}
}
In form1, upon pressing Edit:
void OnButtonEdit_Click(object sender, ...)
{
using (var form = new FormEdit())
{
Account accountToEdit = this.GetSelectedAccount();
form.Account = accountToEdit;
// or: GetLastAddedAccount if you only want to edit the last added one
var dlgResult = form.ShowDialog(this);
if (dlgResult == DialogResult.OK)
{ // extract the edited Account from the form:
Account editedData = form.Account;
this.UpdateSelectedAccount(editedData);
}
}
}
Like in the examples above I usually decide to have an interface with a property that inserts and extracts Accounts instead of accessing every Account property separately. This allows you to change internals of an Account without having to change all (software) users of this Account
It's all about passing data between forms, So you can use one of following :
set the user input in public string so you can access the strings from other forms by the input form object.
you can pass the user input as constructor parameters and then use the data in your form.
there are also other multiple ways like delegate but i think the 2 previous ways are simple.

Change Textbox text from another frame(container)

I see here lot of similar question, but I still not find answer that help me in situation.
I have two frame(lets say FrameChild), one is "in" another(practically FrameChild is in this frame, lets say FrameMain).
When I insert all parameters in FrameChild and tap on button witch is on bottom of FrameMain I call method that return string...
Now when i get string i need to change textbox text in FrameChild
I have tray many way.
First idea was something like:
FrameChild frm = new FrameChild;
frm.textbox.text = "somestring";
But nothing happen.
Than i thing use some property.
in FrameChield:
public string setTicNo
{
set
{
textBox.Text = value;
}
}
in FrameMain:
FrameChild frm = new FrameChild;
frm.setTicNo = "somestring";
When i debbuging I get value, but textbox still is empty...
On the end I try to bind textbox text on setTicNo;
public string setTicNo
{
get
{
return setTicNo;
}
set
{
setTicNo = value;
}
}
Xaml:
Text = {Binding setTicNo, Mode=TwoWay,UpdateSourceTrigger=Explicit}
(here i try use more bindings, but every time i get infinite loop.
Please help , I not have more ideas..
Thanx
Did you try building a single view model and bind it to both frames, if it was passed by ref which is the default it will change the value once you do.
A side note implement a INOTIFYPROPERTYCGANGED in the View model

form data and class objects

EDIT::
This might be simple for some but right now it has me confused. I am working on a project and when the submit button is pressed,create either a person or an employee based on the above checkbox. Put all of the form data into the class object using either the constructor or properties. Display all of the class information using the ToString method and a messagebox.
My question is::
When it is asking when the submit button is pressed, create a person or an employee based on the above checkbox.Would I use what is above the checkbox or below.
Also to put all of the form data into the class object using either the constructors or properties. I'm Not to sure how to do this.
Display all of the class information using a ToString and a messagebox. I understand how to do a messagebox but not with a ToString.
Now I already have two classes and those names are Members and Employees. Under the Members I have Name, Age, and COB. Under the employees I have Salary and JobTitle. The only time that the salary and jobtitle comes up if the user check the checkbox that says is person employee.
I am sorry if I confuse people I myself is kinda confused with what is being asked. The software I am using is Microsoft Visual C# 2010 Expressed.
The code I have so far don't know if it is right or not:
private void button1_Click(object sender, EventArgs e)
{
Members obj = new Members(); <---This is what is I am assuming being asked when
obj.Name = ""; its says create either a person or an employee
obj.Age = ""; based on the above checkbox.
obj.COB = "";
Employess obj1 = new Employess(); <-- here I am trying to put all of the form
obj1.Salary = ""; data into the class object using either
obj1.JobTitle = ""; the constructor or properties.
Console.WriteLine(obj.ToString());<--- this is the messagebox I am being asked to do its not all the way done.
}
From what I get from your code is you have taken two classes for employees and members and you want to store their information in objects of respective classes based upon your checkbox selection. I suppose you are working in windows forms because you have specified the button_click event.
If that's the case:
private void button1_Click(object sender, EventArgs e)
{
if(checkbox1_Member.Checked==true)
{
Members obj = new Members();
obj.Name = "";
obj.Age = "";
obj.COB = "";
MessageBox.Show(obj.Name+ " :: " +"obj.Age.ToString());
}
else if(checkbox2_Employee.Checked==true)
{
Employees obj1 = new Employees();
obj1.Salary = "";
obj1.JobTitle = "";
MessageBox.Show (obj1.Salary.ToString()+ " ::"+obj.JobTitle.ToString());
}
}
Your question is quite vague but let's make a ton of assumptions:
You have a checkbox you've renamed to 'checkEmployess'. (I'm not sure if you meant 'employee' but let's just go with it.)
You have text boxes on your form for all of the stuff the user has entered with sensible names.
All the input is in text at the moment.
So, you need to check whether the checkbox is ticked/checked with an if statement and create the correct sort of object:
private void button1_Click(object sender, EventArgs e)
{
object dude; // if you use inheritance then this could be of the base class's type
if (this.checkEmployess.Checked)
{
// it's an employess
Employess employee = new Employess();
employess.Salary = textSalary.Text; // this copies the value of the control into your object
employess.JobTitle = textJobTitle.Text; // however for this example we've assumed every control is a text control and your object has only string properties
dude = employess;
}
else
{
// it's a member
Members member = new Members();
member.Name = textName.Text;
member.Age = textAge.Text; // this in particular should be made numeric
member.COB = textCOB.Text;
dude = member;
}
MessageBox.Show(dude);
}
That's the basic object creation done. You could add a ToString method to these two classes to format their properties for display. (This approach is a bit crude but will work so stick with this for now.)
Improvements you can then make are:
Use input controls that are more suitable for the type of input. E.g. numeric controls for numbers, &c.
Use object initializers for constructing these objects.
Use methods to correctly format these two types of objects for display).

Click a custom control and show some variables related to it in another control

in my Win Forms app I create an array of dynamic custom controls inside a loop. These, lets call them 'boxes', are like my basic pieces of information. I also create string arrays in other parts of the code that contain the information of this 'boxes', so that for example string[3] is a variable of box[3] and so does stringa[3], stringb[3], stringc[3]... all the arrays with the same index are related to the box with that index. Hope I make myself clear.
Only 2 of this strings are shown in 2 labels inside each custom control 'box' in the array, but the others are there because I want to make something so that when the user clicks one of these controls the other strings can be shown in another control. Sort of something like "More Information...". All the 'boxes' in the array need to have the same event handler because I create +100.
To put it more into context, each custom control 'box' in the array shows the Symbol and the Price of a stock and I want that when the user clicks on each stock more quote information is shown on another special control which is like a placeholder for "More info".
I am thinking of 2 ways to do it:
If I could "detect" the index of the clicked control (which is the same in the strings related to it), I could just set this to an int j and all I have to do is show all the strings a,b,c... with index j. Unfortunately I cannot find a way to do this, maybe it is not even possible.
The other way I have thought is to create some properties for my custom control which "store" this variables, and in my app instead of assigning strings I would set properties for each control, which I could later retrieve when the control is clicked. I haven't tryed this because I don't know exactly how to do it.
What do you think? Do you know how can I achieve this or do you have a different idea that will work? Please help! Thanks in advance.
It's kind of a broad implementation question since there are countless ways you could implement something like this.
If you are creating two collections, one with the buttons and one with the information, you potentially could just assign each of the buttons 'Tag' properties to point to the corresponding info and assign a generic OnClick event handler that displays the info.. something like:
infoControl.text = ((InfoClass)((Button)Sender.Tag)).pieceOfInformation;
But again there are many ways to do this, and the choice comes down to how you store your information.
For your first method, you could have a property of your custom control that is the index.
public class Box : Control
{
// ...existing code
private int index;
public int Index
{
get
{
return index;
}
set
{
index = value;
}
}
}
OR
For your second method, you could have a property of your custom control that is the additional info string.
public class Box : Control
{
// ...existing code
private string extraInfo;
public string ExtraInfo
{
get
{
return extraInfo;
}
set
{
extraInfo = value;
}
}
}
In either case, you could then access the proper information right in your click handler for the "box".
i don't know about the first way - got to noodle around more, but in the second way you can extended your custom or built-in control: for example:
public class ExtendedLabel: Label
{
public string[] MoreInfo { get; set; }
}
and initialize it
public TestForm()
{
InitializeComponent();
ExtendedLabel label = new ExtendedLabel();
label.MoreInfo = new string[] { "test" };
this.Controls.Add(label);
label.AutoSize = true;
label.Location = new System.Drawing.Point(120, 87);
label.Name = "label1";
label.Size = new System.Drawing.Size(35, 13);
label.TabIndex = 0;
label.Text = label.MoreInfo[0];
}
And later in your event handler you can use the inside information

Sharing a variable between two winforms

I have a winforms application.
I have a textbox on one form (call F1) and when a button is clicked on this form (call F2), it launches another form.
On F2, I want to set a string via a textbox (and save it to a variable in the class), and then when I close this form, the string will appear in a label in F1.
So I am basically sharing variables between both forms. However, I can't get this to work correctly. How would this code look?
I would add a new property to form2. Say it's for a phone number. Then I'd add a friend property m_phone() as string to form 2. After showing an instance of form2 but before closing it, you can refer to the property m_phone in form1's code.
It's an additional level of indirection from Matthew Abbott's solution. It doesn't expose form2 UI controls to form1.
EDIT
e.g.:
public string StoredText
{
get;
private set;
}
inside the set you can refer to your UI control, like return textBox1.text. Use the get to set the textbox value from an earlier load.
And:
public string GetSomeValue()
{
var form = new F2();
form.ShowDialog();
return form.StoredText;
}
Just ensure that StoredText is populated (or not, if appropriate) before the form is closed.
Are you showing the second form as a dialog, this is probably the best way to do it. If you can avoid doing shared variables, you could do the following:
public string GetSomeValue()
{
var form = new F2();
form.ShowDialog();
return form.TextBox1.Text;
}
And called in code:
Label1.Text = GetSomeValue();
This might not be the most efficient way of approaching, but you could create a class called DB (database). Inside this class, create variables like
public static bool test or public static bool[] test = new bool[5];
In your other forms, you can just create an instance. DB db = new DB(); then grab the information using db.test = true/false. This is what I've been doing and it works great.
Sorry, I'm only like a year late.

Categories