登录需求很常见,不管BS项目还是CS项目,你几乎都需要一个登录界面来开启你的项目。登录时通过查询验证数据库的用户名和密码,来判断是否登录成功。那么一个完整的登录过程需要有哪几步呢?
1,登录界面(Login):
两个Lable控件: 用户名 和 密码
对应两个Lable有用户名框和密码框两个TextBox控件: accountTextBox,passwordTextBox ,
三个Button控件:登录(loginBouttom),注册(registeredButton),关闭(closeBouttom)
Check控件:在密码框后面,是否显示密码(visibilityCheck)
2,注册界面(Registered)
三个Lable控件: 用户名 , 密码 和 重复密码
对应三个个Lable有用户名框和密码框三个TextBox控件: accountTextBox,passwordTextBox ,repeatPasswordTextBox
两个Button控件:注册(registeredButton),关闭(closeBouttom)
3,用到的工具类和静态类(前两个类我都专门写在一篇博客,这里就不上代码了)
XmlToolClass:XML工具类 保存琐细的数据,比如记录最后一次成功登录的账号,没必要因为存一个账号而在数据库新建一个表。
SqlHelpClass:简化对数据库的操作
LoginInfo:用户类,应用单件模式,保存用户登录状态
LoginInfo类代码:

/// <summary> /// 用户类 /// </summary> public class LoginInfo { //用户帐号,登录帐号 private string _Account = ""; public string Account { get { return _Account; } set { _Account = value; } } //用户名 private string _PassWord = ""; public string PassWord { get { return _PassWord; } set { _PassWord = value; } } //登录时间 private DateTime _LoginTime; public DateTime LoginTime { get { return _LoginTime; } set { _LoginTime = value; } } private static LoginInfo _CurrentUser = null; //应用单件模式,保存用户登录状态 public static LoginInfo CurrentUser { get { if (_CurrentUser == null) _CurrentUser = new LoginInfo(); return _CurrentUser; } } }
4,注册
注册的话数据库需要一个表
create table usersTable ( accout char(20) primary key, password char(20) not null )
账号是主键,不能重复,密码这里不为空就行,实际需要给个最小长度,这个最小长度不一定需要在数据库加check,也可以在注册的检测代码里校对。
5,登录
就是对数据库的查询
首先两个textbox上的数据是否符合==> 查询账号是否存在==>查询密码是否正确
登录成功后,需要把数据记录在LoginInfo里面,不然一点击登录这些数据就拿不到了。
接下来分别把各个步骤的代码上一遍
Login窗口是该实例的主窗口
Windows窗体文件(From窗口)类文件里尽量不要写太多关于逻辑控制和数据操作的代码,小练习MVC框架用不上,但是MVC的编程思想要有,即使是在做一个很小的程序。

public partial class login : Form { public bool IsClose { get; set; } public login() { InitializeComponent(); AccoutTextBox.Text = XmlToolClass.GetLastTimeSuccessfulLoginAccount("账号"); PasswordTextBox.PasswordChar = '*';//设置显示*隐藏密码 IsClose = false; //利用XmlToolClass从xml文件中获取最后一次成功登录的账号 } private void registeredButton_Click_1(object sender, EventArgs e) { Registered registered = new Registered(); this.Hide();//隐藏当前窗口 registered.ShowDialog();//显示注册窗口 } private void visibilityCheck_CheckedChanged(object sender, EventArgs e) { if (visibilityCheck.Checked) { PasswordTextBox.PasswordChar = new char();//设置密码可见 } else { PasswordTextBox.PasswordChar = '*';//设置显示*隐藏密码 } } private void loginBoutton_Click(object sender, EventArgs e) { string strSqlAccout = "select count(*) from usersTable where accout='" + AccoutTextBox.Text.Trim() + "'"; string strSqlPassword = "select count(*) from usersTable where accout='" + AccoutTextBox.Text.Trim() + "' and password='" + PasswordTextBox.Text + "'"; if (AccoutTextBox.Text == "" || PasswordTextBox.Text == "") MessageBox.Show("账号和密码不能为空!", "登陆提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation); else if (Convert.ToInt16( SqlHelpClass.ExecuteScalar(strSqlAccout)) <= 0) //利用SqlHelpClass查询账号 MessageBox.Show("账号不存在!", "登陆提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation); else if (Convert.ToInt16(SqlHelpClass.ExecuteScalar(strSqlPassword)) <= 0) //利用SqlHelpClass验证密码 MessageBox.Show("密码错误!", "登陆提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation); else { //LoginInfo为静态类,登陆成功后此静态类用于存储账号,用户名,登陆时间 LoginInfo.CurrentUser.Account = AccoutTextBox.Text; LoginInfo.CurrentUser.PassWord = PasswordTextBox.Text; LoginInfo.CurrentUser.LoginTime = DateTime.Now; XmlToolClass.SetSuccessfulLoginAccount("账号", LoginInfo.CurrentUser.Account);//将账号写入xml this.DialogResult = DialogResult.OK; } } private void closeButton_Click(object sender, EventArgs e) { IsClose = true; this.Close(); } }
Registered窗口类
public partial class Registered : Form { public Registered() { InitializeComponent(); } private void closButton_Click(object sender, EventArgs e) { this.Close(); } private void registeredButton_Click(object sender, EventArgs e) { string strSqlAccout = "select count(*) from usersTable where accout='" + accountTextBox.Text.Trim() + "'"; if (accountTextBox.Text == "" || accountTextBox.Text == "") MessageBox.Show("账号和密码不能为空!", "登陆提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation); else if ( int.Parse(SqlHelpClass.ExecuteScalar(strSqlAccout).ToString()) > 0) //利用SqlHelpClass查询账号 MessageBox.Show("账号已存在!", "登陆提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation); else if (passwordTextBox.Text!=repeatPassword.Text) //利用SqlHelpClass验证密码 MessageBox.Show("两次密码不相同!", "登陆提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation); else { try { if (SqlHelpClass.AddData("usersTable", accountTextBox.Text, passwordTextBox.Text) > 0) MessageBox.Show("注册成功"); else MessageBox.Show("注册失败,请重新注册"); } catch { } } } }
最后就是测试,新建一个主页窗口(Home),模拟登陆成功后,跳转的窗口。
有两个Label控件,用来显示登陆时数据。
上面Login的代码到最后面登陆为什么不跳转窗口反而是来一段 this.DialogResult = DialogResult.OK;,有一些人看不懂。
如果以Login为主窗口的话,那么正常的操作应该是,先隐藏Login窗口个在实例化一个Home窗口,然后使得Home窗口可见。我们不能关闭Login,因为关闭主窗口,整个应用程序就直接退出了。
所以我们需要做一些改动,使得Login窗口变成在主窗口弹出前的一个判断性质的窗口——模式对话框。
模式对话框,当它弹出后,本应用程序其他窗口将不再接受用户输入,只有该对话框响应用户输入,在对它进行相应操作退出后,其他窗口才能继续与用户交互。
我们对Program类的main方法做些改变,main方法是应用程序的主入口点。
static class Program { /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); login login1; do //模式窗口之间循环,直到密码正确 { login1 = new login();//实例化Login login1.ShowDialog();//将Login实例窗体显示为模式对话框 if (login1.IsClose) break; } while (!login1.DialogResult.Equals(DialogResult.OK));//登录成功才显示主窗体 if(login1.DialogResult.Equals(DialogResult.OK)) Application.Run(new Home());// Application.Run()方法运行主窗口 } }
这里用到了一个do while循环,因为注册窗口也是模式对话框,对于两个模式对话框之间切换,我只能说能力有限。基于两个模式对话框相互操作和切换太难,只能重复关闭窗口,实例化窗口,来维持
登录界面与注册界面直至登录成功或者退出,因为do while 循环 所以只能添加一个IsClose布尔值属性来判断是否终止循环来退出。