Something wrong while passing property from one class to the other - c#

I am having 3 classes. One is AuthenticateUser which let me to set and get user information such as username and password. In other class, AddEntryWindow is a WinForm in which I am trying to display content of the Password and UserName properties from AuthenticateUser. third class is another WinForm class which let me to set username and password to the AuthenticateUser class. As I try, in this simplified example, to display username and password from a WinForm class I am getting a blank message box. Also, when using another message box in AuthenticateUserWindow I am able to get the content of properties.
How can I fix this to be able to view content of the property in AddEntryWindow class? I have been staring blank for past hour on this.
Probably it's something with line: AuthenticateUser authenticateUser = new AuthenticateUser(); which create a new object. But where would it go instead?
Most likely problem in AddEntryWindow.cs
using System;
using System.Windows.Forms;
// Needed to be used with StringBuilder
using System.Text;
// Needed to be used with ArrayList.
using System.Collections;
namespace Store_Passwords_and_Serial_Codes
{
public partial class AddEntryWindow : Form
{
// Making authentication possible.
AuthenticateUser authenticateUser = new AuthenticateUser();
// Default constructor to initialize the form.
public AddEntryWindow()
{
InitializeComponent();
}
private void btnAddEntry_Click(object sender, EventArgs e)
{
MessageBox.Show(authenticateUser.UserName + authenticateUser.Password);
}
}
}
AuthenticateUser.cs
using System;
namespace Store_Passwords_and_Serial_Codes
{
class AuthenticateUser
{
private string userName, password;
public AuthenticateUser()
{
}
public AuthenticateUser(string userNamePassed, string passwordPassed)
{
this.userName = userNamePassed;
this.password = passwordPassed;
}
public string UserName
{
get
{
return userName;
}
set
{
userName = value;
}
}
public string Password
{
get
{
return password;
}
set
{
password = value;
}
}
}
}
AuthenticateUserWindow.cs
using System;
using System.Windows.Forms;
namespace Store_Passwords_and_Serial_Codes
{
public partial class AuthenticationWindow : Form
{
// Most important log in information needs to be entered
// for encrypting and decrypting binary file.
AuthenticateUser authenticateUser;
public AuthenticationWindow()
{
InitializeComponent();
}
private void btnClose_Click(object sender, EventArgs e)
{
// Closing Authentication Window form.
Close();
}
private void btnClear_Click(object sender, EventArgs e)
{
// Clearing text boxes txtUserName and txtPassword
// after Clear Form button is clicked.
txtUserName.Clear();
txtPassword.Clear();
}
private void btnAuthenticate_Click(object sender, EventArgs e)
{
if (txtUserName.Text == string.Empty || txtPassword.Text == string.Empty)
{
MessageBox.Show("Please fill both information first.");
}
else
{
// Passing the values to object AuthenticateUser.
authenticateUser = new AuthenticateUser(txtUserName.Text, txtPassword.Text);
MessageBox.Show(authenticateUser.UserName + authenticateUser.Password);
Close();
}
}
}
}
Regards.

Like John said, you need to change the code as follows:
public partial class AddEntryWindow : Form
{
// Making authentication possible.
AuthenticateUser authenticateUser = new AuthenticateUser();
// Default constructor to initialize the form.
public AddEntryWindow()
{
InitializeComponent();
}
private void btnAddEntry_Click(object sender, EventArgs e)
{
new AuthenticationWindow(authenticateUser).ShowDialog();
MessageBox.Show(authenticateUser.UserName + authenticateUser.Password);
}
}
...
public partial class AuthenticationWindow : Form
{
// Most important log in information needs to be entered
// for encrypting and decrypting binary file.
AuthenticateUser authenticateUser;
public AuthenticationWindow(AuthenticateUser user)
{
InitializeComponent();
authenticateUser = user;
}
...
private void btnAuthenticate_Click(object sender, EventArgs e)
{
if (txtUserName.Text == string.Empty || txtPassword.Text == string.Empty)
{
MessageBox.Show("Please fill both information first.");
}
else
{
// Passing the values to object AuthenticateUser.
authenticateUser.UserName = txtUserName.Text;
authenticateUser.Password = txtPassword.Text;
MessageBox.Show(authenticateUser.UserName + authenticateUser.Password);
Close();
}
}
}

You are creating two separate instances of AuthenticateUser, one in AddEntryWindow and one in AuthenticationWindow. Just because they have the same name doesn't mean they are in the same scope.
Without knowing how your program works I can't give you the best option, but one would be to create a static class that acts as a global for AuthenticateUser. Another option would be to figure out how to pass the information between your Forms. If you create the AuthenticationWindow from the AddEntryWindow you could set an instance of AuthenticateUser as public in AuthenticationWindow and then access it when the window closes before you dispose of it.

Here i could infer a bit of workaround for your question, i do hope it is what your looking for.
If your invoking or launching AddWindowEntry form from AuthenticationWindow assuming that AuthenticationWindow is the parent form, then you have created AuthenticateUser object in this class. Pass this instance to the child form i.e AddWindowEntry and set to a local variable there. So when btnAddEntry_Click event gets executed, then you can display this local variables content in the message box.

Related

C# class string used on a another Form

i have a little problem on my form Login when i Login, i want send my username on the string username in my class functions.
And when my Main Form is loaded i want this class functions get the username from my form login with my username
i have try something like this:
My form login:
public Functions FUNCTIONS = new Functions(); //for my class Functions
FUNCTIONS.Username = "Username123";
My class Functions:
public class Functions
{
public string Username = ""; //empty
}
and my Main form after login
public Functions FUNCTIONS = new FUNCTIONS();
private void Main_Load(object sender, EventArgs e)
{
MessageBox.Show("Welcome "+ FUNCTIONS.Username " to my application.");
}
When my Main Form is loaded it's don't show the username string it's keep this empty, thanks for your time and your help for fix my problem.
You could try
public class Functions
{
public static string Username { get; set; }
}
Also this way you dont need to initialize Functions with new keyword, Functions.Username would be enough
It would work because static keyword ensures that there is one instance of this peroperty for yor application lifetime. Also you could consider using singleton pattern with dependency injection, read more there :
https://csharpindepth.com/articles/singleton
Don't create new 2nd time, new creates an another Functions instance. Pass to main Form the existing one instead and assign it to the field in main Form.
public partial class LoginForm : Form
{
private Functions functions = new Functions();
public LoginForm()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
functions.Username = "Username123";
new MainForm.Show(functions);
this.Close();
}
}
public partial class MainForm : Form
{
private Functions functions;
public MainForm()
{
InitializeComponent();
}
public MainForm(Functions f) : this()
{
functions = f;
}
private void MainForm_Load(object sender, EventArgs e)
{
MessageBox.Show(functions.Username);
}
}

Visual C# custom class type settings won't save

I have a custom class and a collection thereof that I want to use to create entries in my Settings.default. I managed to set the types in the designer using the browse(...) button on my namespace, and in a given session, it works. I can store and get values from my classes (or rather, objects of those classes).
But the settings don't get saved.
I have used this method to implement my custom classes in my Settings, and I'm trying tips such as this one to have them saved - but no luck here.
How will I be able to save custom object classes?
The types within the final class are trivial, nothing but strings, integers and booleans.
Update:
It's not a collection serialization issue, a simple class containing a single string also won't persist. I changed my code to a simpler example.
using System;
using System.Windows.Forms;
using System.Configuration;
namespace tester
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
if(Properties.Settings.Default.MySetting== null)
{
MessageBox.Show("MySetting is null");
Properties.Settings.Default.MySetting = new saveme(); // this saveme will be accessible just fine for the duration of the session, but it won't persist.
}
textBox1.Text = Properties.Settings.Default.MySetting.somestring; // will always be "initial value" as per initialization of saveme()
}
private void button1_Click(object sender, EventArgs e)
{
Properties.Settings.Default.MySetting.somestring = textBox1.Text;
Properties.Settings.Default.Save();
}
}
[Serializable()]
public class saveme : ApplicationSettingsBase // class containing data
{
private string Somestring = "initial value";
[UserScopedSetting()]
[DefaultSettingValue("default value")]
[SettingsSerializeAs(SettingsSerializeAs.Binary)]
public string somestring
{
get { return Somestring; }
set { Somestring = value; }
}
}
}
It will always end up with MySetting being null
I was able to reproduce the non-persisting issue and was able to make things work.
Here is a simple working example if you want to create a new setting by code.
public partial class Form1 : Form
{
private FormSettings frmSettings1 = new FormSettings();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.textBox1.Text = frmSettings1.FormText;
}
private void button1_Click(object sender, EventArgs e)
{
frmSettings1.FormText = textBox1.Text;
this.Close();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
frmSettings1.Save();
}
}
//Application settings wrapper class
sealed class FormSettings : ApplicationSettingsBase
{
[UserScopedSettingAttribute()]
public String FormText
{
get { return (String)this["FormText"]; }
set { this["FormText"] = value; }
}
}
I did not add a new setting on the project properties settings tab.
I also avoided using the Properties.Settings.Default.
I found out that Properties.Settings.Default does not persist and by testing it only works (persist) for the settings added to the project properties settings tab.
In case you want to try it you should instead use MyNameSpace.Properties.Settings.Default instead of plain Properties.Settings.Default. It makes a difference.

Return information from another form to the main form

I have a main form, MainForm, that opens up another form, NewPasswordForm. This happens once I click the AddButton on the main form. The code is below:
MainForm : Form {
private void AddButton_Click(object sender, EventArgs e) {
NewPasswordForm newPassword = new NewPasswordForm();
using (NewPasswordForm form = new NewPasswordForm())
{
var result = form.ShowDialog();
if (result == DialogResult.OK)
{
Console.WriteLine("Made it work");
Login login = new Login();
//Need to get passed the login information from the NewPasswordForm
//so that I can add it to a list of Logins
}
}
}
}
NewPaswordForm has four fields to fill out. Once I hit the add button in the NewPasswordForm I want
public partial class NewPasswordForm : Form {
Login login = new Login();
private void AddButton_Click(object sender, EventArgs e) {
//Do stuff with the four fields to creat a Login
//pass the login along with the DialogResult.OK below.
this.DialogResult = DialogResult.OK;
}
My question is how do I go about passing that information once I click the AddButton on the NewPasswordForm?
Add a public property to your NewPasswordForm, set it's value inside the method, and then query this property from the main form.
Upd: I am taking this out of comments as requested. The question was: Why not to define and fire event along with the required data, and catch it from the main form. The answer is that the event driven architecture is meant for designing REACTIVE systems, responding to asynchronous events given by different components. But in this case the role of such an event is performed by the button pressed. There is no reason to add any asynchronous behavior besides this one. After the button is pressed, it is DETERMINED that the property is set and ready to be read. The event would be in place in case we wanted run some process after button click, and wait until it is finished.But This is not the case
Here's a code sample of the public property thing I (and Eugene Sh.) mentioned:
public partial class NewPasswordForm : Form {
public Login LoginInfo { get; private set; }
private void AddButton_Click(object sender, EventArgs e) {
LoginInfo = new Login();
//Do stuff with the four fields to create a Login
//pass the login along with the DialogResult.OK below.
this.DialogResult = DialogResult.OK;
}
}
Then once you're back on the MainForm:
MainForm : Form {
private void AddButton_Click(object sender, EventArgs e) {
//NewPasswordForm newPassword = new NewPasswordForm(); // Don't need this line
using (NewPasswordForm form = new NewPasswordForm())
{
var result = form.ShowDialog();
if (result == DialogResult.OK)
{
Console.WriteLine("Made it work");
Login login = form.LoginInfo;
// do something
}
}
}
}
Edit: I just realized there were two NewPasswordForms instantiated in your AddButton_Click method. You don't need two for this operation.

How to list all forms of solution explorer in property of custom control?

I have created a login validation custom control. It has two properties named username and password, which are showed in properties window when included in the project.
I want to create a property which will show all forms list in a ComboBox-like manner to the properties window, so that the project programmer can specify which form will be open when login successful. The custom control has two textboxes and one button. How should I do it?
namespace WindowsFormsApplication18
{
public partial class UserControl1 : UserControl
{
private string uname=null;
private string pword=null;
public string username
{
get
{
return uname;
}
set
{
uname = value;
}
}
public string password
{
get
{
return pword;
}
set
{
pword=value;
}
}
public UserControl1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text == username && textBox2.Text == password)
{
MessageBox.Show("login successful");
}
else
MessageBox.Show("wrong password");
}
}
}
so that the project programmer can specify which form will be open when login successful
That really is not the task of your usercontrol. Maybe the programmer wants to do something else upon a successful login.
Create a LoggedIn event which you fire upon a successful login, and subscribe to that event from the code where you use the control. The programmer can then, in that event handler, do as he or she desires.
To get all the Forms in the current executing Module, you can do something like this:
//Must add using System.Reflection; first
public class LoginForm : Form {
public LoginForm(){
InitializeComponent();
Load += (s,e) => {
forms = GetAllForms();
comboBox1.DataSource = forms;
comboBox1.DisplayMember = "Text";//Show the caption
};
}
List<Form> forms;
public List<Form> GetAllForms(){
List<Form> forms = new List<Form>();
foreach (Type t in Assembly.GetExecutingAssembly().GetModules()[0].GetTypes())
{
if (t == GetType()) continue;//Don't add LoginForm
if (t.IsSubclassOf(typeof(Form)))
{
forms.Add((Form)t.GetConstructor(Type.EmptyTypes).Invoke(null));
}
}
return forms;
}
private void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text == username && textBox2.Text == password)
{
MessageBox.Show("login successful");
//Show the selected form
forms[comboBox1.SelectedIndex].Show();
}
else
MessageBox.Show("wrong password");
}
}

Passing String to another forms from one form in c# [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to Pass String to another forms from one form in c#
C# Query : When I login to my software I select the desired username using combobox. After I login, I want to see the username text in the main window on the toolstrip.
I tried get and set method but something is going wrong. Can you please help me out? Thanks in advance.
Form 1:
public partial class login : Form
{
public login()
{
InitializeComponent();
}
public string username
{
get{
return a.ToString();}
}
public string a;
private void button1_Click(object sender, EventArgs e)
{
a = comboBox1.Text;
Form main1 = new main();
main1.Show();
// rest is the code for login.
}
}
Form 2:
public partial class main : Form
{
public main()
{
InitializeComponent();
}
public string username
{
set { toolStripLabel1.Text = value; }
}
private void main_Load(object sender, EventArgs e)
{
Form home = new home();
home.MdiParent = this;
home.WindowState = FormWindowState.Maximized;
home.Show();
}
}
Here Home is form3 a childform which opens in Main form. at load event of Main form itself.
Somebody just answered this question for you a few minutes ago!? And as far as I could tell, it was a perfectly appropriate answer, so why don't you just implement that?
https://stackoverflow.com/a/9872043/1017882
Replace the main_Load code with this:
private void main_Load(object sender, EventArgs e)
{
login home = new login();
home.MdiParent = this;
home.WindowState = FormWindowState.Maximized;
home.ShowDialog(); // waits for the home form to be closed
this.username = home.username;
}
Im not sure where you call your login class.
But you could pass an instance of your main form and set the value from there.
public login(main mainInstance)
{
//... login etc.
mainInstance.UserName = comboBox1.Text;
}
or have the login method return a user object or string.
I can't post this as a comment, otherwise it would be unreadable, but unless I am mistaken:
Form home = new home()
Would not even compile considering the only two classes are main and login
While you could correct the code and declare the form the correct way
login home = new login();
It seems easier just to use a static variable in a case like this.
I believe best way is to use events:
Form1:
public partial class login : Form
{
public delegate void sendStringDelegate(string s);
public event sendStringDelegate sendString;
public login()
{
InitializeComponent();
}
public string username
{
get{
return a.ToString();}
}
public string a;
private void button1_Click(object sender, EventArgs e)
{
a = comboBox1.Text;
sendString(a);
// rest is the code for login.
}
}
Form2:
public partial class main : Form
{
login log = new login();
public main()
{
InitializeComponent();
log.sendString += new login.sendStringDelegate(setString);
}
public void setString(string s)
{
whatever.text = s;
}
public string username
{
set { toolStripLabel1.Text = value; }
}
private void main_Load(object sender, EventArgs e)
{
Form home = new home();
home.MdiParent = this;
home.WindowState = FormWindowState.Maximized;
home.Show();
}
}
code not tested so there might be some errors
Also you could use static event:
change
public event sendStringDelegate sendString;
to
public static event sendStringDelegate sendString;
remove login log = new login();
change
log.sendString += new login.sendStringDelegate(setString);
to
login.sendString += new login.sendStringDelegate(setString);

Categories

Resources