currently my window is like this with the edit and delete button disabled. In order to enable the buttons, user have to login with the administrator type. Right now, I already login with the administrator type from the member type. The disabled buttons supposed to be enabled after I logged in with the administrator type, but it is not.
Is there any way to enable the button, after the form opened with the buttons disabled?
Here is the images:
As you can see on the below image, there is a admin login button with edit and delete buttons disabled. (Main System Form):
Administrator Login (Privelege Form)
Here is the code that I am using:
public class SystemManager
{
public static void AdminLogin(string _value1, string _value2, Form _windowsForm, TextBox _windowsTextBox)
{
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
string query = "SELECT * FROM [Member] WHERE [Username] = #Username";
connection.Open();
using (OleDbCommand command = new OleDbCommand(query, connection))
{
command.Parameters.Add("#Username", OleDbType.VarChar);
command.Parameters["#Username"].Value = _value1;
using (OleDbDataReader reader = command.ExecuteReader())
{
if (reader.Read())
{
string password = (string)reader["Password"];
string userType = (string)reader["UserType"];
_isValidPassword = BCrypt.ValidateHash(_value2, password);
if (userType == "Administrator")
{
_isAdministrator = true;
}
else if (userType != "Administrator")
{
_isAdministrator = false;
}
if (_isValidPassword && _isAdministrator)
{
Authenticate _authenticate = new Authenticate();
_authenticate.ShowDialog();
ShowMessageBox("Authenticated.", "Success", 2);
UserInformation.isAdministrator = true;
_windowsForm.Hide();
_windowsForm.Close();
}
}
if (!_isValidPassword || !_isAdministrator)
{
Authenticate _authenticate = new Authenticate();
_authenticate.ShowDialog();
ShowMessageBox("Either username or password incorrect or you are not administrator. Please try again.", "Error", 1);
ClearTextBoxes(_windowsForm.Controls);
_windowsTextBox.Focus();
}
reader.Close();
}
}
connection.Close();
}
}
}
public partial class MainSystem: Form
{
void MainSystem_Load(object sender, EventArgs e)
{
UserPrivelege();
}
void UserPrivelege()
{
if (UserInformation.CurrentLoggedInUserType == "Member")
{
this.button3.Enabled = false; // Edit Button
this.button4.Enabled = false; // Delete Button
this.button7.Enabled = false;
this.button9.Enabled = true; // Admin Login Button
}
else if (UserInformation.CurrentLoggedInUserType == "Administrator" || UserInformation.isAdministrator)
{
this.button3.Enabled = true; // Edit Button
this.button4.Enabled = true; // Delete Button
this.button7.Enabled = true;
this.button9.Enabled = false; // Admin Login Button
}
}
}
public partial class Privelege : Form
{
void button1_Click(object sender, EventArgs e) // OK Button
{
Check();
}
void Check()
{
if (this.textBox1.Text == string.Empty || string.IsNullOrWhiteSpace(this.textBox1.Text))
{
SystemManager.ShowMessageBox("Username field required.", "Information", 2);
}
else if (this.textBox2.Text == string.Empty || string.IsNullOrWhiteSpace(this.textBox2.Text))
{
SystemManager.ShowMessageBox("Password field required.", "Information", 2);
}
else
{
SystemManager.AdminLogin(this.textBox1.Text, this.textBox2.Text, this, this.textBox1);
}
}
Thank you.
I really appreciate your answer.
There are several architectural issues here which when resolved will also make this function the way you want. First of all it is not ideal to call a function from a form which will act upon that form. It is a much better practice to return what is needed from that function and have the code to digest that result in the form which it affects. Let's try a simple example of what the login button could do:
private void btnLogin_Click(object sender, EventArgs e)
{
var login = new LoginForm();
login.ShowDialog();
var result = login.DialogResult == System.Windows.Forms.DialogResult.Yes;
if (result)
{
button2.Enabled = true;
button3.Enabled = true;
}
}
Obviously the only way this would work is if your login for was setting its DialogResult property, which is a simple way to pass a result from a modal dialog. We still have the issue of converting a login result to that value. This can be addressed in the login button of the dialog, and the login method it calls.
private void btnDialogLogin_Click(object sender, EventArgs e)
{
// Form validation here...
var result = SystemManager.AdminLogin(NameButton.Text, PassButton.Text);
DialogResult = DialogResult.No;
if (result)
{
DialogResult = DialogResult.Yes;
}
this.Close();
}
Now we have to change the AdminLogin method to a boolean:
public class SystemManager
{
public static bool AdminLogin(string _value1, string _value2)
{
// Database and evluation...
if(isAdmin)
{
return true;
}
return false;
}
}
This will make it easy to pass values as they are needed, without each object knowing more details about the other than is necessary. If the admin login needs to pass more information than just if the user is an admin, than create a class which contains all the different things one might want to know about the user's login and pass that as a return instead.
what you can do here is, once the user clicks login on your first form, you can send a boolean value to the constructor of your second form, say true for admin and false for others and depending on this value you can enable or disable your button.
The form load event, MainSystem_Load(), is only fired once (at first initialization). The UserPrivelege() function isn't called after the admin login. You will need to invoke that functionality after the admin logs in.
assign value to UserInformation.CurrentLoggedInUserType and on click of Admin login button open your login form as dialog and after close of this form call UserPrivelege(); fuction
Admin login onclick :-
PrivelegeForm frm= new LoginForm();
DialogResult result= frm.ShowDialog();
if (result==DialogResult.Ok)
{
UserPrivelege();
}
don't forget to assign your static variable UserInformation.CurrentLoggedInUserType
Related
I have a login screen and I need to pass username to my main form (for getting permissions etc.). Here is my code:
//Login
private void button1_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(txtUser.Text))
{
//Show warning
}
else if (string.IsNullOrEmpty(txtPass.Text))
{
//Show warning
}
using (DataTable dt = LookupUser(txtUser.Text)) //Look into SQL data table for username and password
{
if (dt.Rows.Count == 0)
{
//Show warning
}
else
{
string dbPassword = Convert.ToString(dt.Rows[0]["pass"]);
string appPassword = Encrypt(txtPass.Text);
if (string.Compare(dbPassword, appPassword) == 0)
{
//I need to pass username value to myForm...
DialogResult = DialogResult.OK;
}
else
{
//Show warning
}
}
}
//Program.cs
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
DialogResult result;
using (var loginForm = new Login())
result = loginForm.ShowDialog();
if (result == DialogResult.OK)
{
Application.Run(new myForm());
}
}
What would be the best way to pass value from loginForm to Program.cs and myForm?
In login form
public string UserName {get; private set;}
if (string.Compare(dbPassword, appPassword) == 0)
{
UserName = txtUser.Text;
//I need to pass username value to myForm...
DialogResult = DialogResult.OK;
}
else
{
//Show warning
}
in main
DialogResult result;
using (var loginForm = new Login())
result = loginForm.ShowDialog();
if (result == DialogResult.OK)
{
var username = loginForm.UserName;
Application.Run(new myForm(username));
}
Expose username as a string property of your login form class. This way you'll be able to fetch it after the form will be closed (it will still remain in memory).
This is the best way to transfer data from one form to another, On the LoginForm.cs write like this:
ex.UserName = txtUserName.text;
Password=txtPassword.text;
MainForm mainForm = new MainForm(UserName,Password);
this.Hide();
mainForm.Show();
In the MainForm.cs edit the
public MainForm ()
{
}
like this:
public MainForm(string userName,string password){
}
it is simply use EF on your codes
just like below
}
Siman_dbEntities db = new Siman_dbEntities();
public string UserNameLogedIn;
private void btnLogin_Click(object sender, EventArgs e)
{
var login = from b in db.Tbl_Users.Where(b => b.Username == txtUsername.Text && b.Password == txt_Password.Text)
select b;
if (login.Count()==1)
{
this.Hide();
main frmmain = new main();
frmmain.Show();
}
var query = db.Tbl_Users.Where(c => c.Username == txtUsername.Text).Single();
UserNameLogedIn = query.Name.ToString();
}
I have created a link button in aspx form which check availablity of login email address and its functionality is as.
protected void lnkCheckAvailable_Click(object sender, EventArgs e)
{
SystemUserBL bl = new SystemUserBL(SessionContext.SystemUser);
ds = new DataSet();
bl.FetchForLoginEmailAddress(ds, txtLoginEmailAddress.Text);
if (ds.Tables[0].Rows.Count > 0)
{
valDuplicatePassword.Visible = true;
valDuplicatePassword.Text = "<b>This User Name is already in use by another user.</b>";
}
else
{
valDuplicatePassword.Visible = true;
valDuplicatePassword.Text = "<b>Congratulations! " + txtLoginEmailAddress.Text + " is available.</b>";
}
}
It's working fine when user will click on check availability link button. There is another button "Save" which saves the user information in the table. Now my issue is that if it displays "This User Name is already in use by another user." message the information is still saved in the database. Please tell me how to prevent this!!!
You can return true or false based on user name exists in database or not. You can create a method which will check user availability.
When user press save button you will call that method if method returns true it means user exists.
private bool CheckUserAvailability()
{
SystemUserBL bl = new SystemUserBL(SessionContext.SystemUser);
ds = new DataSet();
bl.FetchForLoginEmailAddress(ds, txtLoginEmailAddress.Text);
if (ds.Tables[0].Rows.Count > 0)
{
valDuplicatePassword.Visible = true;
valDuplicatePassword.Text = "<b>This User Name is already in use by another user.</b>";
return true;
}
else
{
valDuplicatePassword.Visible = true;
valDuplicatePassword.Text = "<b>Congratulations! " + txtLoginEmailAddress.Text + " is available.</b>";
return false;
}
}
You can also call this method on link click.
protected void lnkCheckAvailable_Click(object sender, EventArgs e)
{
CheckUserAvailability();
}
You will call this method on Save button if user don't exist than save information in database.
protected void Savebtn_Click(object sender, EventArgs e)
{
if(CheckUserAvailability() == false)
{
SaveUserInfoToDataBase();
}
}
abstract class User
{
public string Username;
public string Password;
public virtual bool Validate(string username, string password)
{
Username = "";
Password = "";
if (password == Password && username == Username)
{
MessageBox.Show("Incorrect password or username");
return true;
}
else
{
return false;
}
}
form code:
private void btnSubmit_Click(object sender, EventArgs e)
{
UserAdmin admin = new UserAdmin();
UserEmployee empp = new UserEmployee();
bool validateAdmin = admin.Validate(txtUsername.Text, txtPassword.Text);
bool validateEmpp = empp.Validate(txtUsername.Text, txtPassword.Text);
if (validateAdmin==true || validateEmpp == true )
{
this.Hide();
// Create a new instance of the options class
Options opt = new Options();
opt.Closed += (s, args) => this.Close();
// Show the settings form
opt.Show();
}
When the first validation is false it keeps checking the second validation as well.By doing so 2 message boxes are being popped up.
EDIT:
Can you show only one message box instead of 2? it only shows the message box if the username or password is incorrect
You can combine validations in conditional expression:
if(admin.Validate(txtUsername.Text, txtPassword.Text) && empp.Validate(txtUsername.Text, txtPassword.Text))
{
... // is ok
}
else
{
... // when either Validate from left to right is not ok
}
This way if admin.Validate return false, then empp is not validated.
I would say that the standard way to stop execution of the code - is throwing an exception. So what You could do - is throw a 'ValidationExceptio' and implement appropriate ex handlers
To stop showing two message boxes, Remove the message box from method and include it into the click event. So the method will be like this:
public virtual bool Validate(string username, string password)
{
if (password == Password && username == Username)
{
return true;
}
else
{
return false;
}
}
And the click event will be like :
private void btnSubmit_Click(object sender, EventArgs e)
{
UserAdmin admin = new UserAdmin();
UserEmployee empp = new UserEmployee();
bool validateAdmin = admin.Validate(txtUsername.Text, txtPassword.Text);
bool validateEmpp = empp.Validate(txtUsername.Text, txtPassword.Text);
if (validateAdmin)
{
MessageBox.Show("Successfylly login as Admin");
//operation here
}
else if (validateEmpp)
{
MessageBox.Show("Successfylly login as " + txtUsername.Text);
//operation here
}
else { MessageBox.Show("Incorrect password or username"); }
}
I have two forms i.e., frmLogin and frmDash. I have username and password saved in credentials.txt file. My default run form is frmLogin. Now my problem is, when application starts it checks username and password from credentials.txtand directly shows frmDash. Its working, but problem is, with frmDash , frmLogin is also opening at back. How to solve this?
I have tried this(Form1 is frmLogin):
private void Form1_Load(object sender, EventArgs e)
{
try
{
var credentialLines = File.ReadAllLines(Environment.CurrentDirectory + "\\credentials\\credentials.txt");
if (credentialLines.Any())
{
UserName_reLogin = credentialLines[0];
Password_reLogin = credentialLines[1];
if (LoginUser(Log_API, UserName_reLogin, Password_reLogin))
{
logIn_Status = "true";
GlolbalUtil.LogIn_Status = logIn_Status;
//this.Hide();
frmDash frmDash = new frmDash();
frmDash.Owner = this;
frmDash.Show();
txtUsername.Text = "";
txtPassword.Text = "";
//GlolbalUtil.accept_status = "1";
this.Enabled = false;
}
else
{
MessageBox.Show("Please Check Username and password");
}
}
else
{
this.Enabled = true;
}
}
catch
{
}
}
Move to your login logic to Program.cs in the Main function for something like this
var credentialLines = File.ReadAllLines(Environment.CurrentDirectory + "\\credentials\\credentials.txt");
if (credentialLines.Any()){
UserName_reLogin = credentialLines[0];
Password_reLogin = credentialLines[1];
if (LoginUser(Log_API, UserName_reLogin, Password_reLogin)){
Application.Run(new frmDash ());
}else{
Application.Run(new frmlogin());
}
}else
{
Application.Run(new frmlogin());
}
First of all, you should check if the credential exists before opening the login Form.
but anyway to hide forms use this.Hide(); to hide forms
private void FrmLogin_Shown(object sender, EventArgs e)
{
if (GlolbalUtil.authenticate == "true")
{
this.Hide();
}
else if(GlolbalUtil.authenticate == "false")
{
this.Show();
}
}
GlobalUtil.authenticate is global variable to check if user is logged in or not. if user is logged in that means GlobalUtil.authenticate=="true", then only frmLogin will hide otherwise show. worked perfectly.
I am new to C# so my problem is at Login Form.
If my user class is anything other than "admin" every time I hit the submit button it will bring me back to login form. So my statements stops when the condition is not true I'm guessing. here is my code.
--------Edit
Sorry about my newbie limitations
here is what I have:
A sql table with usernames and roles
depending on what role they have the user will load a different form
// Compare strings
private bool CompareStrings(string string1, string string2)
{
return String.Compare(string1, string2, true, System.Globalization.CultureInfo.InvariantCulture) == 0 ? true : false;
}
// button on Login form
public void button1_Click(object sender, EventArgs e)
{
try
{
SqlConnection UGIcon = new SqlConnection();
UGIcon.ConnectionString = "Data Source=BVSQL; Initial Catalog=BV1;user id=jose; password=jones6;";
UGIcon.Open();
SqlCommand cmd = new SqlCommand("SELECT ISNULL(bvuser, '') AS stUsername, ISNULL(bvpassword,'') AS stPassword, ISNULL(bvclass, '') AS stRole FROM BVusertable WHERE bvuser='" + textBox1.Text + "' and bvpassword='" + textBox2.Text + "'", UGIcon);
SqlDataReader dr = cmd.ExecuteReader();
string userText = textBox1.Text;
string passText = textBox2.Text;
//string stRole = "admin";
dr.Read();
{
if
(this.CompareStrings(dr["stUsername"].ToString(), userText) &&
this.CompareStrings(dr["stPassword"].ToString(), passText)
)
{
if (this.CompareStrings(dr["stRole"].ToString(), "admin"))
{
this.DialogResult = DialogResult.OK;
}
else if (this.CompareStrings(dr["stRole"].ToString(), "user"))
{
this.DialogResult = DialogResult.No;
}
}
else
{
//MessageBox.Show("Error");
}
}
dr.Close();
UGIcon.Close();
}
catch (Exception ex)
{
MessageBox.Show("Login Falied");
}
}
here is the Programs.cs
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace BV_SOFT
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Loginf fLogin = new Loginf();
if (fLogin.ShowDialog() == DialogResult.OK)
{
Application.Run(new Home2());
}
else
if (fLogin.ShowDialog() == DialogResult.No)
{
Application.Run(new Home3());
}
else
{
Application.Exit();
}
You're calling ShowDialog twice. Try this:
Loginf fLogin = new Loginf();
DialogResult result = fLogin.ShowDialog();
if (result == DialogResult.OK)
{
Application.Run(new Home2());
}
else if (result == DialogResult.No)
{
Application.Run(new Home3());
}
else
{
Application.Exit();
}
Calling ShowDialog twice will show the form twice. Using this will only show it once. In your code, if the role is not "admin" then the else block is executed, and it calls ShowDialog again which will show the form again, which isn't what you want. Show the form once, store the result, and do your checking on the stored result.
You are only setting the DialogResult to OK when the user has the "admin" role.
In all other cases except when the role is "user" you are leaving the result unset. This will mean that the form won't be dismissed.
Without knowing what your logic is I can't suggest what it should be.