不同用户登录时控制按钮可见性的代码问题求助
解决按钮权限控制失效的问题
我来帮你排查下问题,你的Create_new user按钮显示逻辑没生效,主要有几个关键错误,咱们一步步修正:
问题分析
- 代码顺序错误:你在初始化
SqlDataReader之前就调用了reader.HasRows,这时候reader还没执行查询,根本读不到任何数据,判断逻辑完全走不通。 - 查询参数未赋值:你的SqlCommand里定义了
@USER_ID和@PASS参数,但没有给这些参数添加具体值,数据库查询不到匹配记录,自然不会进入后续的类型判断。 - 数据库字段名不匹配:你的数据库表字段是
UserType,但代码里写的是reader["User_Type"](多了下划线),这会导致读取不到用户类型,UserType变量为空,判断失效。 - 没必要重复查询数据库:登录时已经获取了用户类型,直接用全局变量传递判断即可,重复查库既浪费性能又容易出错。
最优解决方案(使用全局变量)
首先确保你在登录时把用户类型存入全局变量,比如先定义一个静态类:
// 全局变量类,放在项目里的公共位置 public static class GlobalVariables { public static string CurrentUserType { get; set; } public static string CurrentUserName { get; set; } }
然后修改登录代码,赋值全局变量:
try { // 确保数据库连接已打开 conn.Open(); SqlCommand selectCommand = new SqlCommand("SELECT * FROM Login_users WHERE USER_NAME=@USER_NAM AND PASSWORD=@PASSWOR", conn); selectCommand.Parameters.Add(new SqlParameter("USER_NAM", txtusername.Text.ToString())); selectCommand.Parameters.Add(new SqlParameter("PASSWOR", txtpassword.Text.ToString())); string UserType = null; using(SqlDataReader reader = selectCommand.ExecuteReader()) { bool rowfound = reader.HasRows; if (rowfound) { while (reader.Read()) { UserType = reader[2].ToString().Trim(); // 赋值全局变量 GlobalVariables.CurrentUserType = UserType; GlobalVariables.CurrentUserName = txtusername.Text.ToString(); if (UserType == "ADMIN") { MessageBox.Show("Welcome ", "Admin Login", MessageBoxButtons.OK, MessageBoxIcon.Information); Admin_StockControl frm = new Admin_StockControl(); frm.Show(); this.Hide(); } else if (UserType == "STOCK_CON") { MessageBox.Show("Welcome ", "User Login", MessageBoxButtons.OK, MessageBoxIcon.Information); Cashier frm = new Cashier(); frm.Show(); this.Hide(); } } } else { MessageBox.Show(" Invalid User Or Password ", "Login ", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } catch(Exception ex) { // 捕获异常,方便排查问题 MessageBox.Show("登录出错:" + ex.Message); } finally { // 确保连接关闭 if(conn.State == ConnectionState.Open) { conn.Close(); } }
最后修改Admin_Menu_Load方法,直接用全局变量判断按钮可见性:
private void Admin_Menu_Load(object sender, EventArgs e) { // 直接根据全局变量判断,无需再次查询数据库 if (GlobalVariables.CurrentUserType == "ADMIN") { bunifuFlatButton3.Visible = true; } else { // 非管理员都隐藏按钮 bunifuFlatButton3.Visible = false; } }
备选方案(如果必须查询数据库)
如果你确实需要从数据库重新获取用户类型,修正后的代码如下:
private void Admin_Menu_Load(object sender, EventArgs e) { try { conn.Open(); // 只查询需要的UserType字段,提升性能 SqlCommand selectCommand = new SqlCommand("SELECT UserType FROM New_User WHERE User_Name = @UserName", conn); // 使用全局变量里的当前用户名作为参数 selectCommand.Parameters.Add(new SqlParameter("@UserName", GlobalVariables.CurrentUserName)); using(SqlDataReader reader = selectCommand.ExecuteReader()) { if (reader.HasRows) { while (reader.Read()) { // 注意字段名是UserType,不是User_Type string UserType = reader["UserType"].ToString().Trim(); bunifuFlatButton3.Visible = UserType == "ADMIN"; } } else { // 用户不存在时默认隐藏按钮 bunifuFlatButton3.Visible = false; } } } catch(Exception ex) { MessageBox.Show("加载菜单出错:" + ex.Message); bunifuFlatButton3.Visible = false; } finally { if(conn.State == ConnectionState.Open) { conn.Close(); } } }
注意事项
- 始终用
using包裹SqlDataReader和SqlConnection,确保资源自动释放,避免内存泄漏。 - 数据库字段名要和代码里的完全一致,你的表结构是
UserType,不要写成User_Type。 - 全局变量要确保在登录时正确赋值,避免出现空值导致判断错误。
- 记得捕获异常,方便排查运行时的数据库连接或查询错误。
内容的提问来源于stack exchange,提问作者mohamed anver
相关产品推荐
相关产品推荐

