C#基于Sunnyui框架和MVC模式实现用户登录管理
- 1 Controller
- 1.1 UserManagementController.cs(控制器入口)
- 2 Model
- 2.1 UserRepository.cs(用户管理模型)
- 2.2 User.cs(用户结构体)
- 2.3 SQLiteHelper.cs(数据库工具类)
- 3 View
- 3.1 LoginView.cs(用户登录窗体)
- 3.2 UserManagementForm(用户信息管理窗体)
- 3.2.1 UserManagementForm.cs
- 3.2.2 UserManagementForm.Designer.cs
- 3.3 UserUpdataForm.cs(添加、修改用户对话框)
- 4 扩展类
说明
- 类库结构如上图;
- 外部调用通过控制器入口调用
- 用户信息存储于数据库表中,路径:输出目录中userdata.db;
- 初始化自动生成开发者账号信息;
1 Controller
1.1 UserManagementController.cs(控制器入口)
using System;
using System.Windows.Forms;
using UserManage.Extensions;
using UserManage.Model;
using UserManage.View;namespace UserManage.Controller
{public class UserManagementController{private const string PermissionPrompt = "权限不足,请登录管理员账号";private readonly LoginView _loginForm;private readonly UserRepository _userRepository;private readonly UserManagementForm _userManagementForm;private User _currentUser;public UserType UserPermission => _currentUser?.UserType ?? UserType.Null;public UserManagementController(){_loginForm = new LoginView();_userRepository = new UserRepository();_userManagementForm = new UserManagementForm();_loginForm.LoginClicked += LoginForm_LoginClicked;_userManagementForm.AddUserClicked += UserManagementForm_AddUserClicked;_userManagementForm.ModifyUserClicked += UserManagementForm_ChangeUserPasswordClicked;_userManagementForm.DeleteUserClicked += UserManagementForm_DeleteUserClicked;}public UserManagementController(UserManagementForm userManagementForm){this._userManagementForm = userManagementForm;}public void RunLoginForm(){_loginForm.ShowDialog();}public void RunUserManagementForm(){if (_currentUser == null){UserManageExtension.ShowMsg(PermissionPrompt);return;}if (_currentUser.UserType != UserType.Developer && _currentUser.UserType != UserType.Admin){UserManageExtension.ShowMsg(PermissionPrompt);return;}LoadUser();_userManagementForm.ShowDialog();}private void LoadUser(){var table = _userRepository.GetUserTable();table.Columns[0].ColumnName = "用户名";table.Columns[1].ColumnName = "密码";table.Columns[2].ColumnName = "用户类型";_currentUser = _userRepository.GetUser(_currentUser.Username, _currentUser.Password);if (_currentUser.UserType != UserType.Developer){for (int i = 0; i < table.Rows.Count; i++){if (table.Rows[i][2].ToString().GetUserTypeByText() == UserType.Developer){table.Rows[i][1] = "******";}}}_userManagementForm.LoadUsers(table);}private void LoginForm_LoginClicked(object sender, EventArgs e){string username = _loginForm.Username;string password = _loginForm.Password;_currentUser = _userRepository.AuthenticateUser(username, password);if (_currentUser != null){_loginForm.Hide();}else{UserManageExtension.ShowMsg("用户名或密码错误!");}}private void UserManagementForm_AddUserClicked(object sender, EventArgs e){UserUpdataForm addDialog = new UserUpdataForm();switch (UserPermission){case UserType.Developer:addDialog.RefreshAddUserInfo();addDialog.AddUserType(UserType.Developer, UserType.Admin, UserType.NormalUser);break;case UserType.Admin:addDialog.RefreshAddUserInfo();addDialog.AddUserType(UserType.NormalUser);break;default:UserManageExtension.ShowMsg(PermissionPrompt);return;}addDialog.EnterClicked += (o, args) =>{try{string username = addDialog.UserName;string password = addDialog.Password;UserType userType = addDialog.UserType;if (addDialog.UserType == UserType.Null){UserManageExtension.ShowMsg("请选择用户类型!");return;}if (UserManageExtension.Confirm($"请确认添加用户信息" +$"{Environment.NewLine}用户名:{username}" +$"{Environment.NewLine}密码:{password}" +$"{Environment.NewLine}用户类型:{userType.GetUserTypeText()}" +$"{Environment.NewLine}确认添加?")){_userRepository.AddUser(username, password, userType);addDialog.DialogResult = DialogResult.OK;}}catch (Exception ex){UserManageExtension.ShowMsg(ex.Message);}};addDialog.ShowDialog();LoadUser();}private void UserManagementForm_DeleteUserClicked(object sender, EventArgs e){var selectUser = _userManagementForm.SelectUser;if (selectUser == null){UserManageExtension.ShowMsg(PermissionPrompt);return;}if (selectUser.UserType == UserType.Developer){UserManageExtension.ShowMsg("无法删除开发者账户", "警告");return;}if (!UserManageExtension.Confirm($"您正在删除用户[{selectUser.Username}],删除后将无法恢复,请确认是否继续?"))return;switch (UserPermission){case UserType.Developer:case UserType.Admin:_userRepository.DeleteUser(selectUser.Username);break;default:UserManageExtension.ShowMsg(PermissionPrompt);return;}LoadUser();}private void UserManagementForm_ChangeUserPasswordClicked(object sender, EventArgs e){var selectUser = _userManagementForm.SelectUser;if (selectUser == null){UserManageExtension.ShowMsg("请选择需要修改的用户");return;}if (selectUser.UserType == UserType.Developer && _currentUser.UserType != UserType.Developer){UserManageExtension.ShowMsg(PermissionPrompt);return;}UserUpdataForm updataDialog = new UserUpdataForm();switch (UserPermission){case UserType.Developer:updataDialog.RefreshUdpataUserInfo(selectUser);updataDialog.AddUserType(UserType.Developer, UserType.Admin, UserType.NormalUser);break;case UserType.Admin:updataDialog.RefreshUdpataUserInfo(selectUser);updataDialog.AddUserType(UserType.NormalUser);break;default:UserManageExtension.ShowMsg(PermissionPrompt);return;}updataDialog.EnterClicked += (o, args) =>{try{if (updataDialog.UserType == UserType.Null){UserManageExtension.ShowMsg("请选择用户类型!");return;}string username = updataDialog.UserName;string password = updataDialog.Password;UserType userType = updataDialog.UserType;if (UserManageExtension.Confirm($"用户[{username}],密码修改为{Environment.NewLine}{password}{Environment.NewLine}是否确认修改?")){_userRepository.ChangePassword(username, password, userType.GetUserTypeText());updataDialog.DialogResult = DialogResult.OK;}}catch (Exception ex){UserManageExtension.ShowMsg(ex.Message);}};updataDialog.ShowDialog();LoadUser();}}
}
2 Model
2.1 UserRepository.cs(用户管理模型)
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.Diagnostics.Eventing.Reader;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using UserManage.Extensions;namespace UserManage.Model
{public class UserRepository{private const string TableName = "User";private string connectionString = "Data Source=users.db;Version=3;";private SQLiteHelper _sqLiteHelper;public const string DeveloperName = "Veizu";public const string DeveloperPassword = "Aa123456";public UserRepository(){CreateUserTable();EnsureDeveloperExists();}private void CreateUserTable(){string datasource = Path.Combine(Application.StartupPath, "userdata.db");string tableInfo = TableName + "( " + "Username CHAR(50) PRIMARY KEY," + "Password CHAR(50)," + "UserType CHAR(50)" + ")";if (File.Exists(datasource)){_sqLiteHelper = SQLiteHelper.OpenConnection(datasource);if (_sqLiteHelper.IsExistsTable(TableName)){_sqLiteHelper.CreateTableSql(tableInfo);}}else{_sqLiteHelper = SQLiteHelper.OpenConnection(datasource, true, tableInfo);}}private void EnsureDeveloperExists(){try{AddUser(DeveloperName, DeveloperPassword, UserType.Developer);}catch (Exception ex){}}public User AuthenticateUser(string username, string password){return GetUser(username, password);}public void IsValidUsernamePassword(string username, string password){string pattern = @"^[a-zA-Z\u4e00-\u9fa5][a-zA-Z0-9\u4e00-\u9fa5]*$";var ret = Regex.IsMatch(username, pattern);if (!ret){throw new ArgumentException("用户名第一个字符必须是英文字母或中文开头,仅允许包含中文、英文和数字。");}pattern = @"^[a-zA-Z0-9]+$";ret = Regex.IsMatch(password, pattern);if (!ret){throw new ArgumentException("用户密码仅允许字母和数字。");}const int passwordLength = 6;if (password.Length < passwordLength){throw new ArgumentException($"用户密码不得少于{passwordLength}个字符。");}}public bool IsUserExists(string username, string password = null){return GetUser(username, password) != null;}public DataTable GetUserTable(){var table = _sqLiteHelper.Select(TableName);return table.Copy();}public User GetUser(string username, string password = null){User user = null;var table = GetUserTable();foreach (DataRow row in table.Rows){if (row[nameof(User.Username)].ToString().Equals(username)){if (!string.IsNullOrWhiteSpace(password)){if (row[nameof(User.Password)].ToString().Equals(password)){UserType userType = row[nameof(User.UserType)].ToString().GetUserTypeByText();user = new User(username, password, userType);}}else{user = new User(username);}}}return user;}public void AddUser(string username, string password, UserType userType){IsValidUsernamePassword(username, password);if (IsUserExists(username)){throw new ArgumentException("该用户名已存在,请选择其他用户名。");}var parameter1 = new SQLiteParameter { ParameterName = nameof(User.Username), Value = username };var parameter2 = new SQLiteParameter { ParameterName = nameof(User.Password), Value = password };var parameter3 = new SQLiteParameter { ParameterName = nameof(User.UserType), Value = userType.GetUserTypeText() };_sqLiteHelper.Insert(TableName, parameter1, parameter2, parameter3);}public void DeleteUser(string username){_sqLiteHelper.Delete(TableName, nameof(User.Username), username);}public void ChangePassword(string username, string newPassword, string newUserType){IsValidUsernamePassword(username, newPassword);string updateQuery = $"UPDATE {TableName} SET {nameof(User.Password)} = '{newPassword}',{nameof(User.UserType)} = '{newUserType}' WHERE {nameof(User.Username)} = '{username}';";_sqLiteHelper.ExecuteSql(updateQuery);}}
}
2.2 User.cs(用户结构体)
namespace UserManage.Model
{public enum UserType{Null = 1,Developer = 3,Admin = 5,NormalUser = 7,}public class User{public string Username { get; set; }public string Password { get; set; }public UserType UserType { get; set; }public User(string username, string password, UserType userType){Username = username;Password = password;UserType = userType;}public User(string username){Username = username;}}
}
2.3 SQLiteHelper.cs(数据库工具类)
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.IO;
using System.Linq;
using System.Reflection;namespace UserManage.Model
{public class SQLiteHelper{public static SQLiteConnection _conn;private static SQLiteConnectionStringBuilder _connstr;public static SQLiteHelper OpenConnection<T>(string datasource) where T : class{if (!File.Exists(datasource)) SQLiteConnection.CreateFile(datasource);var sqLite = new SQLiteHelper();_conn = new SQLiteConnection();_connstr = new SQLiteConnectionStringBuilder { DataSource = datasource };_conn.ConnectionString = _connstr.ToString();_conn.Open();var tableName = Path.GetFileNameWithoutExtension(datasource);string query = $"SELECT name FROM sqlite_master WHERE type='table' AND name='{tableName}';";using (SQLiteCommand command = new SQLiteCommand(query, _conn)){// 执行查询并获取结果object result = command.ExecuteScalar();// 如果结果不为空,则表存在if (result == null){sqLite.CreateTable<T>();}}return sqLite;}/// <summary>/// 打开数据库/// </summary>/// <param name="datasource">数据库路径</param>/// <param name="isCreate">是否创建数据库文件</param>/// <param name="tableInfo">创建数据库文件时同时创建的表结构信息;例如:TableName(ListIndex INTEGER, ListTime CHAR(23), ListSpeed INTEGER, ListRemark CHAR(50))</param>/// <returns>返回SQLiteHelper实例</returns>public static SQLiteHelper OpenConnection(string datasource, bool isCreate, string tableInfo = null){if (isCreate) SQLiteConnection.CreateFile(datasource);var sqLite = new SQLiteHelper();_conn = new SQLiteConnection();_connstr = new SQLiteConnectionStringBuilder { DataSource = datasource };_conn.ConnectionString = _connstr.ToString();_conn.Open();if (isCreate) sqLite.CreateTableSql(tableInfo);return sqLite;}/// <summary>/// 打开数据库/// </summary>/// <param name="datasource">数据库路径</param>/// <returns>返回SQLiteHelper实例</returns>public static SQLiteHelper OpenConnection(string datasource) => OpenConnection(datasource, false);/// <summary>/// 关闭/// </summary>public void CloseConnection(){if (_conn.State == ConnectionState.Closed)return;_conn.Close();_conn.Dispose();_connstr.Clear();}/// <summary>/// 执行自定义SQL语句,/// </summary>/// <param name="sql">自定义SQL语句</param>/// <returns>返回影响行数</returns>public int ExecuteSql(string sql){using (var cmd = _conn.CreateCommand()){cmd.CommandText = sql;return cmd.ExecuteNonQuery();}}public int CreateTable<T>() where T : class{string createTableQuery = GenerateCreateTableQuery(typeof(T));// 创建SQLite命令对象using (SQLiteCommand command = new SQLiteCommand(createTableQuery, _conn)){// 执行SQL命令command.ExecuteNonQuery();}return 0;}static string GenerateCreateTableQuery(Type type){// 获取实体类名称string tableName = type.Name;// 初始化SQL语句字符串构建器System.Text.StringBuilder query = new System.Text.StringBuilder();query.Append($"CREATE TABLE IF NOT EXISTS {tableName} (");// 获取实体类的所有属性PropertyInfo[] properties = type.GetProperties();for (int i = 0; i < properties.Length; i++){PropertyInfo property = properties[i];// 获取属性名称string columnName = property.Name;// 获取属性类型string columnType = GetSqliteType(property.PropertyType);query.Append($"{columnName} {columnType}");if (i < properties.Length - 1){query.Append(", ");}}query.Append(");");return query.ToString();}static string GetSqliteType(Type type){// 根据C#类型映射到SQLite类型if (type == typeof(int) || type == typeof(long)){return "INTEGER";}else if (type == typeof(string)){return "TEXT";}else if (type == typeof(double) || type == typeof(float)){return "REAL";}else if (type == typeof(List<DateTime>) || type == typeof(List<double>)){return "BLOB";}else{return "TEXT";}}/// <summary>/// 执行自定义SQL语句,/// </summary>/// <param name="tableInfo">表结构信息;例如:TableName(ListIndex INTEGER, ListTime CHAR(23), ListSpeed INTEGER, ListRemark CHAR(50))</param>/// <returns>返回影响行数</returns>public int CreateTableSql(string tableInfo) => ExecuteSql($"CREATE TABLE {tableInfo}");/// <summary>/// 执行插入操作/// </summary>/// <param name="tableName">表名</param>/// <param name="colName">字段名</param>/// <param name="value">参数数据</param>/// <returns>int</returns>public int Insert(string tableName, string colName, string value){using (var cmd = _conn.CreateCommand()){cmd.CommandText = $"INSERT INTO {tableName} VALUES(@{colName})";cmd.Parameters.Add(colName, DbType.String).Value = value;return cmd.ExecuteNonQuery();}}/// <summary>/// 执行插入操作/// </summary>/// <param name="tableName">表名</param>/// <param name="parameters">键值对</param>/// <returns>int</returns>public int Insert(string tableName, SQLiteParameter parameters){using (var cmd = _conn.CreateCommand()){// 添加参数到命令对象 cmd.Parameters.Add(parameters);// 构建完整的INSERT语句 string query = $"INSERT INTO {tableName} ({parameters.ParameterName}) VALUES (@{parameters.ParameterName});";cmd.CommandText = query;// 执行命令并返回受影响的行数 return cmd.ExecuteNonQuery();}}/// <summary>/// 从库中删除表/// </summary>/// <param name="tableName"></param>public int DeleteTable(string tableName){using (var cmd = _conn.CreateCommand()){cmd.CommandText = $"DROP TABLE IF EXISTS {tableName}";return cmd.ExecuteNonQuery();}}/// <summary>/// 执行删除操作/// </summary>/// <param name="tableName">表名</param>/// <param name="colName">字段名</param>/// <param name="value">参数数据</param>/// <returns>int</returns>public int Delete(string tableName, string colName, object value){using (var cmd = _conn.CreateCommand()){cmd.CommandText = $"DELETE FROM {tableName} WHERE {colName} = @value;";cmd.Parameters.Add("value", DbType.Object).Value = value;return cmd.ExecuteNonQuery();}}/// <summary>/// 执行查询操作/// </summary>/// <param name="tableName">表名</param>/// <returns>DataTable</returns>public DataTable Select(string tableName){var dt = new DataTable();var cmd = _conn.CreateCommand();cmd.CommandText = $"select * from {tableName}";var dao = new SQLiteDataAdapter(cmd);dao.Fill(dt);cmd.ExecuteNonQuery();dao.Dispose();return dt.Copy();}public bool IsExistsTable(string tableName){string cmdText = $"select count(*) from sqlite_master where name='{tableName}' and type='table';";int count = ExecuteSql(cmdText);return count > 0;}public bool IsExistsData(string tableName, Dictionary<string, object> parameter){string query = $"SELECT COUNT(*) FROM {tableName} WHERE ";foreach (var key in parameter.Keys){query += $"{key} = @{key}";}query += $";";SQLiteCommand command = new SQLiteCommand(query, _conn);foreach (var key in parameter.Keys){command.Parameters.AddWithValue($"@{key}", parameter[key]);}int count = Convert.ToInt32(command.ExecuteScalar());return count > 0;}/// <summary>/// 执行插入操作/// </summary>/// <param name="tableName">表名</param>/// <param name="parameters">键值对字典</param>/// <returns>int</returns>public int Insert(string tableName, params SQLiteParameter[] parameters){int count = -1;try{using (var cmd = _conn.CreateCommand()){string query = $"INSERT INTO" +$" {tableName}" +$" ({string.Join(",", parameters.Select(p => p.ParameterName))})" +$" VALUES ({string.Join(",", parameters.Select(p => "@" + p.ParameterName))});";cmd.Parameters.AddRange(parameters);cmd.CommandText = query;count = cmd.ExecuteNonQuery();}return count;}catch (Exception ex){throw ex;}}/// <summary>/// 批量插入/// </summary>/// <param name="tableName"></param>/// <param name="col"></param>/// <param name="list"></param>public void Insert(string tableName, string[] col, List<object[]> list){var cmd = _conn.CreateCommand();SQLiteTransaction transaction = _conn.BeginTransaction();cmd.Transaction = transaction;try{object[] obj = list.First();var parameters = new List<SQLiteParameter>();for (int i = 0; i < col.Length; i++){parameters.Add(new SQLiteParameter(col[i], obj[i]));}string sql = $"INSERT INTO" +$" {tableName}" +$" ({string.Join(",", parameters.Select(p => p.ParameterName))})" +$" VALUES ({string.Join(",", parameters.Select(p => "@" + p.ParameterName))});";foreach (var value in list){parameters = new List<SQLiteParameter>();for (int i = 0; i < col.Length; i++){parameters.Add(new SQLiteParameter(col[i], value[i]));}cmd.Parameters.AddRange(parameters.ToArray());cmd.CommandText = sql;cmd.ExecuteNonQuery();}transaction.Commit();}catch (Exception e){}}/// <summary>/// 执行更新操作/// </summary>/// <param name="tableName">表名</param>/// <param name="setValues">新数据</param>/// <param name="whereClause">条件</param>/// <param name="parameters">条件数据</param>/// <returns>int</returns>public int Update(string tableName, Dictionary<string, object> setValues, string whereClause, List<SQLiteParameter> parameters){using (var cmd = _conn.CreateCommand()){List<string> setColumns = new List<string>();int index = 0;foreach (var kvp in setValues){setColumns.Add($"{kvp.Key} = @{kvp.Key}");cmd.Parameters.Add(new SQLiteParameter($"@{kvp.Key}", kvp.Value));index++;}string query = $"UPDATE {tableName} SET {string.Join(",", setColumns)} WHERE {whereClause}";cmd.CommandText = query;cmd.Parameters.AddRange(parameters.ToArray());return cmd.ExecuteNonQuery();}}}
}
3 View
3.1 LoginView.cs(用户登录窗体)
using System;
using System.Windows.Forms;
using Sunny.UI;
using UserManage.Model;namespace UserManage.View
{public partial class LoginView : UIForm{private UILabel lblUsername;private UILabel lblPassword;private UITextBox txtUsername;private UITextBox txtPassword;private UIButton btnLogin;public event EventHandler LoginClicked;public string Username => txtUsername.Text;public string Password => txtPassword.Text;public LoginView(){InitializeComponent();InitializeUI();}private void LoginView_VisibleChanged(object sender, EventArgs e){txtUsername.Text = string.Empty;txtPassword.Text = string.Empty;txtUsername.Text = "Veizu";txtPassword.Text = "Aa123456";}private void InitializeUI(){// 设置窗体样式this.Text = "用户登录";this.Size = new System.Drawing.Size(300, 250);this.StartPosition = FormStartPosition.CenterScreen;int locationY = 80;int yInterval = 20;// 用户名标签lblUsername = new UILabel();lblUsername.Location = new System.Drawing.Point(30, locationY);lblUsername.Size = new System.Drawing.Size(80, 25);lblUsername.Text = "用户名:";this.Controls.Add(lblUsername);// 用户名文本框txtUsername = new UITextBox();txtUsername.Location = new System.Drawing.Point(120, locationY);txtUsername.Size = new System.Drawing.Size(150, 25);this.Controls.Add(txtUsername);// 密码标签locationY += yInterval + txtUsername.Height;lblPassword = new UILabel();lblPassword.Location = new System.Drawing.Point(30, locationY);lblPassword.Size = new System.Drawing.Size(80, 25);lblPassword.Text = "密码:";this.Controls.Add(lblPassword);// 密码文本框txtPassword = new UITextBox();txtPassword.Location = new System.Drawing.Point(120, locationY);txtPassword.Size = new System.Drawing.Size(150, 25);txtPassword.PasswordChar = '*';this.Controls.Add(txtPassword);// 登录按钮locationY += yInterval + txtPassword.Height;btnLogin = new UIButton();btnLogin.Size = new System.Drawing.Size(100, 30);int btnLoginX = txtPassword.Location.X + txtPassword.Width - btnLogin.Width;btnLogin.Location = new System.Drawing.Point(btnLoginX, locationY);btnLogin.Text = "登录";btnLogin.Click += btnLogin_Click;this.Controls.Add(btnLogin);}private void btnLogin_Click(object sender, EventArgs e){LoginClicked?.Invoke(this, EventArgs.Empty);}}
}
3.2 UserManagementForm(用户信息管理窗体)
3.2.1 UserManagementForm.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Sunny.UI;
using UserManage.Extensions;
using UserManage.Model;namespace UserManage.View
{public partial class UserManagementForm : UIForm{public User SelectUser{get{if (dgv_User.CurrentCell != null){var row = dgv_User.Rows[dgv_User.CurrentCell.RowIndex];string username = row.Cells[0].Value.ToString();string password = row.Cells[1].Value.ToString();UserType userType = row.Cells[2].Value.ToString().GetUserTypeByText();return new User(username, password, userType);}else{return null;}}}public event EventHandler AddUserClicked;public event EventHandler ModifyUserClicked;public event EventHandler DeleteUserClicked;public UserManagementForm(){InitializeComponent();InitializeUI();}private void InitializeUI(){// 设置窗体样式this.Size = new Size(800, 600);this.Text = "用户管理";this.StartPosition = FormStartPosition.CenterScreen;}/// <summary>/// 设置数据表样式/// </summary>private void SetDgvStyle(UIDataGridView table){try{table.ClearSelection();//int index = dgvStandard.CurrentCell.RowIndex;//获取选中行table.MultiSelect = false; //不可多选table.AllowUserToAddRows = false; //设置不显示添加行table.AllowUserToDeleteRows = false; //设置不允许删除行table.AllowUserToResizeColumns = false; //设置列不可调整table.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; //列名居中table.AllowUserToResizeRows = false; //设置行不可调整table.RowHeadersVisible = false; //设置表头不显示行标题table.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; //列填充控件显示区域table.CausesValidation = false; //焦点table.ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single; //边框样式table.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize; //列高调整table.RowsDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; //单元格内容居中table.ReadOnly = true; //只读设置table.RowHeadersWidth = 4; //列宽设置(按照权重设置时需要先添加列)table.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders; //设置列表头不可调整table.RowTemplate.Height = 28; //设置行高table.ScrollBars = ScrollBars.Vertical; //显示垂直滚动条table.TabStop = false; //设置无Tab焦点table.VirtualMode = true; //设置可进行数据管理//dgv.Rows[lastTableHeadRow].Frozen = true;//冻结指定行for (var i = 0; i < table.Columns.Count; i++){table.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable; //禁止点击列名排序dgv_User.Columns[i].FillWeight = 1; //按权重分配列宽}}catch (Exception){// ignored}}private void btnAddUser_Click(object sender, EventArgs e){AddUserClicked?.Invoke(this, EventArgs.Empty);}private void btnModifyUser_Click(object sender, EventArgs e){ModifyUserClicked?.Invoke(this, EventArgs.Empty);}private void btnDeleteUser_Click(object sender, EventArgs e){DeleteUserClicked?.Invoke(this, EventArgs.Empty);}public void LoadUsers(DataTable table){dgv_User.DataSource = null;dgv_User.DataSource = table;SetDgvStyle(dgv_User);}}}
3.2.2 UserManagementForm.Designer.cs
namespace UserManage.View
{partial class UserManagementForm{/// <summary>/// Required designer variable./// </summary>private System.ComponentModel.IContainer components = null;/// <summary>/// Clean up any resources being used./// </summary>/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>protected override void Dispose(bool disposing){if (disposing && (components != null)){components.Dispose();}base.Dispose(disposing);}#region Windows Form Designer generated code/// <summary>/// Required method for Designer support - do not modify/// the contents of this method with the code editor./// </summary>private void InitializeComponent(){System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle();System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle();System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle4 = new System.Windows.Forms.DataGridViewCellStyle();System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle5 = new System.Windows.Forms.DataGridViewCellStyle();this.btn_Add = new Sunny.UI.UIButton();this.btn_Updata = new Sunny.UI.UIButton();this.btn_Del = new Sunny.UI.UIButton();this.dgv_User = new Sunny.UI.UIDataGridView();((System.ComponentModel.ISupportInitialize)(this.dgv_User)).BeginInit();this.SuspendLayout();// // btn_Add// this.btn_Add.Cursor = System.Windows.Forms.Cursors.Hand;this.btn_Add.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));this.btn_Add.Location = new System.Drawing.Point(59, 60);this.btn_Add.MinimumSize = new System.Drawing.Size(1, 1);this.btn_Add.Name = "btn_Add";this.btn_Add.Size = new System.Drawing.Size(149, 35);this.btn_Add.TabIndex = 0;this.btn_Add.Text = "添加用户";this.btn_Add.TipsFont = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));this.btn_Add.Click += new System.EventHandler(this.btnAddUser_Click);// // btn_Updata// this.btn_Updata.Cursor = System.Windows.Forms.Cursors.Hand;this.btn_Updata.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));this.btn_Updata.Location = new System.Drawing.Point(233, 60);this.btn_Updata.MinimumSize = new System.Drawing.Size(1, 1);this.btn_Updata.Name = "btn_Updata";this.btn_Updata.Size = new System.Drawing.Size(149, 35);this.btn_Updata.TabIndex = 0;this.btn_Updata.Text = "修改用户";this.btn_Updata.TipsFont = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));this.btn_Updata.Click += new System.EventHandler(this.btnModifyUser_Click);// // btn_Del// this.btn_Del.Cursor = System.Windows.Forms.Cursors.Hand;this.btn_Del.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));this.btn_Del.Location = new System.Drawing.Point(407, 60);this.btn_Del.MinimumSize = new System.Drawing.Size(1, 1);this.btn_Del.Name = "btn_Del";this.btn_Del.Size = new System.Drawing.Size(149, 35);this.btn_Del.TabIndex = 0;this.btn_Del.Text = "删除用户";this.btn_Del.TipsFont = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));this.btn_Del.Click += new System.EventHandler(this.btnDeleteUser_Click);// // uiDataGridView1// dataGridViewCellStyle1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(235)))), ((int)(((byte)(243)))), ((int)(((byte)(255)))));this.dgv_User.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle1;this.dgv_User.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right)));this.dgv_User.BackgroundColor = System.Drawing.Color.White;this.dgv_User.ColumnHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Single;dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;dataGridViewCellStyle2.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255)))));dataGridViewCellStyle2.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));dataGridViewCellStyle2.ForeColor = System.Drawing.Color.White;dataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.Highlight;dataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.HighlightText;dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.True;this.dgv_User.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle2;this.dgv_User.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;dataGridViewCellStyle3.BackColor = System.Drawing.SystemColors.Window;dataGridViewCellStyle3.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));dataGridViewCellStyle3.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(48)))), ((int)(((byte)(48)))), ((int)(((byte)(48)))));dataGridViewCellStyle3.SelectionBackColor = System.Drawing.SystemColors.Highlight;dataGridViewCellStyle3.SelectionForeColor = System.Drawing.SystemColors.HighlightText;dataGridViewCellStyle3.WrapMode = System.Windows.Forms.DataGridViewTriState.False;this.dgv_User.DefaultCellStyle = dataGridViewCellStyle3;this.dgv_User.EnableHeadersVisualStyles = false;this.dgv_User.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));this.dgv_User.GridColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255)))));this.dgv_User.Location = new System.Drawing.Point(39, 122);this.dgv_User.Name = "dgv_User";dataGridViewCellStyle4.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;dataGridViewCellStyle4.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(235)))), ((int)(((byte)(243)))), ((int)(((byte)(255)))));dataGridViewCellStyle4.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));dataGridViewCellStyle4.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(48)))), ((int)(((byte)(48)))), ((int)(((byte)(48)))));dataGridViewCellStyle4.SelectionBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255)))));dataGridViewCellStyle4.SelectionForeColor = System.Drawing.Color.White;dataGridViewCellStyle4.WrapMode = System.Windows.Forms.DataGridViewTriState.True;this.dgv_User.RowHeadersDefaultCellStyle = dataGridViewCellStyle4;dataGridViewCellStyle5.BackColor = System.Drawing.Color.White;dataGridViewCellStyle5.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));this.dgv_User.RowsDefaultCellStyle = dataGridViewCellStyle5;this.dgv_User.RowTemplate.Height = 23;this.dgv_User.SelectedIndex = -1;this.dgv_User.Size = new System.Drawing.Size(901, 503);this.dgv_User.StripeOddColor = System.Drawing.Color.FromArgb(((int)(((byte)(235)))), ((int)(((byte)(243)))), ((int)(((byte)(255)))));this.dgv_User.TabIndex = 1;// // UserManagementForm// this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;this.ClientSize = new System.Drawing.Size(982, 658);this.Controls.Add(this.dgv_User);this.Controls.Add(this.btn_Del);this.Controls.Add(this.btn_Updata);this.Controls.Add(this.btn_Add);this.Name = "UserManagementForm";this.Text = "UserManagementForm__";this.ZoomScaleRect = new System.Drawing.Rectangle(15, 15, 800, 450);((System.ComponentModel.ISupportInitialize)(this.dgv_User)).EndInit();this.ResumeLayout(false);}#endregionprivate Sunny.UI.UIButton btn_Add;private Sunny.UI.UIButton btn_Updata;private Sunny.UI.UIButton btn_Del;private Sunny.UI.UIDataGridView dgv_User;}
}
3.3 UserUpdataForm.cs(添加、修改用户对话框)
using System;
using System.Windows.Forms;
using Sunny.UI;
using UserManage.Extensions;
using UserManage.Model;namespace UserManage.View
{public partial class UserUpdataForm : UIForm{private UILabel lblUsername;private UILabel lblUserType;private UILabel lblPassword;private UITextBox txtUsername;private UIComboBox comUserType;private UITextBox txtPassword;private UIButton btnEnter;public UserType UserType => comUserType.Text.GetUserTypeByText();public string UserName => txtUsername.Text;public string Password => txtPassword.Text;public event EventHandler EnterClicked;public UserUpdataForm(){InitializeComponent();InitializeUI();}private void InitializeUI(){// 设置窗体样式this.Size = new System.Drawing.Size(300, 280);this.StartPosition = FormStartPosition.CenterScreen;int locationY = 80;int yInterval = 20;// 用户名标签lblUsername = new UILabel();lblUsername.Location = new System.Drawing.Point(30, locationY);lblUsername.Size = new System.Drawing.Size(80, 25);lblUsername.Text = "用户名:";this.Controls.Add(lblUsername);// 用户名文本框txtUsername = new UITextBox();txtUsername.Location = new System.Drawing.Point(120, locationY);txtUsername.Size = new System.Drawing.Size(150, 25);this.Controls.Add(txtUsername);// 用户类型locationY += yInterval + txtUsername.Height;lblUserType = new UILabel();lblUserType.Location = new System.Drawing.Point(30, locationY);lblUserType.Size = new System.Drawing.Size(80, 25);lblUserType.Text = "用户类型:";this.Controls.Add(lblUserType);// 用户类型下拉框comUserType = new UIComboBox();comUserType.Location = new System.Drawing.Point(120, locationY);comUserType.Size = new System.Drawing.Size(150, 25);this.Controls.Add(comUserType);// 密码标签locationY += yInterval + comUserType.Height;lblPassword = new UILabel();lblPassword.Location = new System.Drawing.Point(30, locationY);lblPassword.Size = new System.Drawing.Size(80, 25);lblPassword.Text = "密码:";this.Controls.Add(lblPassword);// 密码文本框txtPassword = new UITextBox();txtPassword.Location = new System.Drawing.Point(120, locationY);txtPassword.Size = new System.Drawing.Size(150, 25);this.Controls.Add(txtPassword);// 登录按钮locationY += yInterval + txtPassword.Height;btnEnter = new UIButton();btnEnter.Size = new System.Drawing.Size(100, 30);int btnLoginX = txtPassword.Location.X + txtPassword.Width - btnEnter.Width;btnEnter.Location = new System.Drawing.Point(btnLoginX, locationY);btnEnter.Click += BtnEnterClick;this.Controls.Add(btnEnter);}private void BtnEnterClick(object sender, EventArgs e){EnterClicked?.Invoke(this, EventArgs.Empty);}public void AddUserType(params UserType[] userTypes){if (comUserType != null){foreach (var userType in userTypes){comUserType.Items.Add(userType.GetUserTypeText());}}}public void RefreshAddUserInfo(){txtUsername.Text = string.Empty;txtPassword.Text = string.Empty;comUserType.Text = string.Empty;this.Text = "添加用户";btnEnter.Text = "添加";txtUsername.ReadOnly = false;}public void RefreshUdpataUserInfo(User user){comUserType.Text = user.UserType.GetUserTypeText();txtUsername.Text = user.Username;txtPassword.Text = user.Password;txtUsername.ReadOnly = true;this.Text = "修改用户";btnEnter.Text = "确认";}}
}
4 扩展类
using Sunny.UI;
using UserManage.Model;namespace UserManage.Extensions
{public static class UserManageExtension{public static string GetUserTypeText(this UserType type){switch (type){case UserType.Developer:return "开发者";case UserType.Admin:return "管理员";case UserType.NormalUser:return "普通用户";default:return "未登录";}}public static UserType GetUserTypeByText(this string text){if (text.Equals(UserType.Developer.GetUserTypeText()))return UserType.Developer;else if (text.Equals(UserType.Admin.GetUserTypeText()))return UserType.Admin;else if (text.Equals(UserType.NormalUser.GetUserTypeText()))return UserType.NormalUser;elsereturn UserType.Null;}public static void ShowMsg(string text, string title = "提示"){UIMessageBox.ShowError(text);}public static bool Confirm(string text){return UIMessageBox.ShowAsk(text);}}
}