Reputation: 2636
I have a OOP question. I have 3 classes. Program (main class), login form and form1.
program runs login that checks for authentication, if this is successful form1 is then run while login closes.
Now the problem I have is, what if I need to pass a variable value to my form1?
The reason is it I wish to use the username login as a variable, pass it to my form1 that then runs the appropiate code to execute specific things.
Basically admin would have full access to controls, but a normal user would have limited access.
here's my code excluding my form1(not needed unless someone wish's to see it).
namespace RepSalesNetAnalysis
{
public partial class LoginForm : Form
{
public bool letsGO = false;
public LoginForm()
{
InitializeComponent();
}
private static DataTable LookupUser(string Username)
{
const string connStr = "Server=server;" +
"Database=dbname;" +
"uid=user;" +
"pwd=*****;" +
"Connect Timeout=120;";
const string query = "Select password From dbo.UserTable (NOLOCK) Where UserName = @UserName";
DataTable result = new DataTable();
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(query, conn))
{
cmd.Parameters.Add("@UserName", SqlDbType.VarChar).Value = Username;
using (SqlDataReader dr = cmd.ExecuteReader())
{
result.Load(dr);
}
}
}
return result;
}
private void buttonLogin_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textUser.Text))
{
//Focus box before showing a message
textUser.Focus();
MessageBox.Show("Enter your username", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
//Focus again afterwards, sometimes people double click message boxes and select another control accidentally
textUser.Focus();
textPass.Clear();
return;
}
else if (string.IsNullOrEmpty(textPass.Text))
{
textPass.Focus();
MessageBox.Show("Enter your password", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
textPass.Focus();
return;
}
//OK they enter a user and pass, lets see if they can authenticate
using (DataTable dt = LookupUser(textUser.Text))
{
if (dt.Rows.Count == 0)
{
textUser.Focus();
MessageBox.Show("Invalid username.", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
textUser.Focus();
textUser.Clear();
textPass.Clear();
return;
}
else
{
string dbPassword = Convert.ToString(dt.Rows[0]["Password"]);
string appPassword = Convert.ToString(textPass.Text); //we store the password as encrypted in the DB
Console.WriteLine(string.Compare(dbPassword, appPassword));
if (string.Compare(dbPassword, appPassword) == 0)
{
DialogResult = DialogResult.OK;
this.Close();
}
else
{
//You may want to use the same error message so they can't tell which field they got wrong
textPass.Focus();
MessageBox.Show("Invalid Password", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
textPass.Focus();
textPass.Clear();
return;
}
}
}
}
private void emailSteve_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
System.Diagnostics.Process.Start("mailto:[email protected]");
}
}
and heres my main class
namespace RepSalesNetAnalysis
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//Application.Run(new LoginForm());
LoginForm fLogin = new LoginForm();
if (fLogin.ShowDialog() == DialogResult.OK)
{
Application.Run(new Form1());
}
else
{
Application.Exit();
}
}
}
}
So to summarise, I need to pass a value from my login class to my form1 class so i can use a condition inside form1 to limit the users interaction.
Upvotes: 3
Views: 6623
Reputation: 52518
Create a class that gathers the data from the form:
class LoginFormResult {
public string UserName { get; set; }
// ....
public DialogResult Result { get; set; }
}
Now create a method on the form (I normally use a static) to execute the form,
public static void Execute(LoginFormData data) {
using (var f = new LoginForm()) {
f.txtUserName.Text = data.UserName ?? "";
// ...
data.Result = f.ShowDialog();
if (data.Result == DialogResult.OK) {
data.UserName = f.txtUserName.Text;
// ....
}
}
}
You can call the form, and handle the result from your Main:
public void Main() {
// ...
var loginData = new LoginData { UserName = "test" };
LoginForm.Execute(loginData);
if (loginData.Result == DialogResult.OK) {
// ....
}
// ...
}
This hides the implementation from the calling method, and also disposes of the form cleanly and as early as possible. The data from the form is available as long as you need it.
Upvotes: 0
Reputation: 3402
You coul pass the required values like this:
LoginForm fLogin = new LoginForm();
if (fLogin.ShowDialog() == DialogResult.OK)
{
Form1 frm = new Form1();
frm.SomeValue = fLogin.txtUser.Text;
Application.Run(frm);
}
else
{
Application.Exit();
}
Upvotes: 1
Reputation: 31847
You need to expose a property in the LoginForm
, and the pass it to the Form1
as a parameter in the constructor. Here are the steps to do it:
1) Add the following code into your LoginForm
class:
public string UserName
{
get
{
return textUser.Text;
}
}
2) Then, change your Form1's constructor to receive the username as a parameter:
private _userName;
public class Form1(string userName)
{
_userName = userName;
}
3) Finally you only need to construct Form1 with the desired parameter:
namespace RepSalesNetAnalysis
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//Application.Run(new LoginForm());
LoginForm fLogin = new LoginForm();
if (fLogin.ShowDialog() == DialogResult.OK)
{
Application.Run(new Form1(fLogin.UserName));
}
else
{
Application.Exit();
}
}
}
Hope it helps.
Upvotes: 4
Reputation: 8008
You could expose it in a property and pass it in the constructor, something like this
LoginForm fLogin = new LoginForm();
if (fLogin.ShowDialog() == DialogResult.OK)
{
Application.Run(new Form1(fLogin.Username));
}
I think you'd need to keep one parameterless constructor for the winforms Designer to work, so you could either try keeping an empty one, or first creating the Form1
and then passing the Username value to it
Upvotes: 3