C# WinForm登录时如何将MS Access数据赋值给全局类变量
C# WinForms登录后获取用户信息并跨窗体访问解决方案
现有代码
你的登录窗体实现代码如下:
private void button1_Click(object sender, EventArgs e) { using (OleDbConnection connection = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\RAV21001310\\OneDrive\\Database1.accdb;")) { connection.Open(); using (OleDbCommand command = new OleDbCommand("SELECT * FROM tblUser WHERE Username=@Username AND Password=@Password", connection)) { command.Parameters.AddWithValue("@Username", username.Text); command.Parameters.AddWithValue("@Password", password.Text); using (OleDbDataReader reader = command.ExecuteReader()) { int count = 0; while (reader.Read()) { count = count + 1; } if (count == 1) { MessageBox.Show("Username and password is correct"); } if (count > 1) { MessageBox.Show("Duplicate username and password"); } if (count == 0) { MessageBox.Show("Username or password incorrect"); } } } connection.Close(); } } public class User { public string Username; public string Password; public string FirstName; public string LastName; public string Gender; public int Age; public int TotalPoints; }
解决方案步骤
1. 优化登录逻辑,读取并实例化User对象
修改登录按钮的点击事件,在验证成功时直接从OleDbDataReader中读取用户数据,赋值给User实例:
private void button1_Click(object sender, EventArgs e) { User loggedInUser = null; using (OleDbConnection connection = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\RAV21001310\\OneDrive\\Database1.accdb;")) { connection.Open(); using (OleDbCommand command = new OleDbCommand("SELECT * FROM tblUser WHERE Username=@Username AND Password=@Password", connection)) { command.Parameters.AddWithValue("@Username", username.Text); command.Parameters.AddWithValue("@Password", password.Text); using (OleDbDataReader reader = command.ExecuteReader()) { if (reader.Read()) { // 读取数据库字段,实例化User对象 loggedInUser = new User { Username = reader["Username"].ToString(), Password = reader["Password"].ToString(), FirstName = reader["FirstName"].ToString(), LastName = reader["LastName"].ToString(), Gender = reader["Gender"].ToString(), Age = Convert.ToInt32(reader["Age"]), TotalPoints = Convert.ToInt32(reader["TotalPoints"]) }; MessageBox.Show("登录成功"); // 打开主窗体并传递用户信息,或者存入全局变量 MainForm mainForm = new MainForm(); mainForm.LoggedInUser = loggedInUser; this.Hide(); mainForm.Show(); } else if (reader.HasRows) { MessageBox.Show("存在重复的用户名和密码,请联系管理员"); } else { MessageBox.Show("用户名或密码错误"); } } } // using块会自动关闭连接,无需手动调用connection.Close() } }
2. 实现跨窗体访问用户信息的两种方式
方式一:窗体间直接传递
在目标窗体(比如MainForm)中添加User类型的属性:
public class MainForm : Form { public User LoggedInUser { get; set; } private void MainForm_Load(object sender, EventArgs e) { // 使用LoggedInUser的信息 labelWelcome.Text = $"欢迎 {LoggedInUser.FirstName} {LoggedInUser.LastName}"; labelPoints.Text = $"当前积分:{LoggedInUser.TotalPoints}"; } }
方式二:全局静态类存储
创建一个静态类来保存当前登录用户,方便所有窗体直接访问:
public static class CurrentUser { public static User LoggedInUser { get; set; } }
在登录成功时赋值:
// 替换窗体传递的代码 CurrentUser.LoggedInUser = loggedInUser;
在其他窗体中直接调用:
private void OtherForm_Load(object sender, EventArgs e) { if (CurrentUser.LoggedInUser != null) { labelUser.Text = CurrentUser.LoggedInUser.Username; labelPoints.Text = CurrentUser.LoggedInUser.TotalPoints.ToString(); } }
3. 额外优化建议
- 把
User类的字段改为属性,符合C#编码规范:
public class User { public string Username { get; set; } public string Password { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Gender { get; set; } public int Age { get; set; } public int TotalPoints { get; set; } }
- 避免直接存储明文密码,数据库中应该存储密码哈希值,登录时比对哈希值而非明文。
- 使用
command.Parameters.Add而非AddWithValue,可以明确指定数据类型,避免潜在的类型转换问题:
command.Parameters.Add("@Username", OleDbType.VarChar).Value = username.Text; command.Parameters.Add("@Password", OleDbType.VarChar).Value = password.Text;
内容的提问来源于stack exchange,提问作者Ahmed Castro
相关产品推荐
相关产品推荐

