登錄需求很常見,不管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布爾值屬性來判斷是否終止循環來退出。