三层架构的补充

##三层架构的补充

1. Form1.cs (主窗体完整代码)

csharp 复制代码
using BusinessLogicLayer;
using Common;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Windows.Forms;

namespace PresentationLayer
{
    public partial class Form1 : Form
    {
        // 业务逻辑层服务对象
        private readonly PaginationService _paginationService;
        private readonly EmployeeService _employeeService;
        private readonly DepartmentService _departmentService;
        private readonly LoginService _loginService;
        private readonly ExportService _exportService;

        // 界面状态变量
        private DataTable _departmentTable;
        private DataGridViewRow _selectedRow;
        private bool _isLoggedIn = false;

        // 分页相关字段
        private int _currentPage = 1;
        private int _totalRecords = 0;
        private int _totalPages = 0;
        private bool _searchMode = false;
        private string _searchConditions = "";
        private readonly string _orderByColumn = AppSettings.DefaultOrderByColumn;

        // 下拉框数据源
        private readonly List<int> _ageList = new List<int>();

        // 界面控件
        private DataGridView dgvEmployee;
        private GroupBox gbEmployeeInfo;
        private TextBox txtPageNumber;
        private TextBox txtPageInput;
        private Button btnGoToPage;
        private Button btnFirstPage;
        private Button btnPreviousPage;
        private Button btnNextPage;
        private Button btnLastPage;
        private Button btnSearch;
        private Button btnAddEmployee;
        private Button btnAddDepartment;
        private Button btnExport;
        private Button btnRefresh;
        private Button btnLogin;
        private Button btnExit;
        private TextBox txtUsername;
        private TextBox txtPassword;
        private CheckBox chkRemember;
        private ComboBox cmbEmployeeName;
        private ComboBox cmbDepartment;
        private ComboBox cmbManager;
        private Label lblPageInfo;
        private Panel pnlLogin;
        private Panel pnlSearch;
        private Panel pnlMain;
        private Panel pnlPagination;
        private Panel pnlButtons;

        public Form1()
        {
            InitializeComponent();
            InitializeServices();
            InitializeUI();
            LoadRememberedPassword();
        }

        #region 初始化和配置

        /// <summary>
        /// 初始化业务逻辑层服务
        /// </summary>
        private void InitializeServices()
        {
            _paginationService = new PaginationService(AppSettings.ConnectionString, AppSettings.PageSize);
            _employeeService = new EmployeeService(AppSettings.ConnectionString);
            _departmentService = new DepartmentService(AppSettings.ConnectionString);
            _loginService = new LoginService(AppSettings.ConnectionString);
            _exportService = new ExportService(AppSettings.ConnectionString);
        }

        /// <summary>
        /// 初始化用户界面
        /// </summary>
        private void InitializeUI()
        {
            // 窗体基本设置
            this.Text = "员工部门管理系统";
            this.Size = new Size(1200, 800);
            this.StartPosition = FormStartPosition.CenterScreen;
            this.FormBorderStyle = FormBorderStyle.FixedSingle;
            this.MaximizeBox = false;

            // 初始化列表
            InitAgeList();

            // 创建界面布局
            CreateLayout();

            // 初始化控件
            InitializeDataGridView();
            InitializeEmployeeInfoPanel();
            InitializePaginationControls();
            InitializeSearchControls();

            // 隐藏数据直到登录
            HideAllData();
        }

        /// <summary>
        /// 创建界面布局
        /// </summary>
        private void CreateLayout()
        {
            // 登录面板 (顶部)
            pnlLogin = new Panel
            {
                Location = new Point(10, 10),
                Size = new Size(1150, 80),
                BorderStyle = BorderStyle.FixedSingle
            };
            this.Controls.Add(pnlLogin);

            // 搜索面板 (登录面板下方)
            pnlSearch = new Panel
            {
                Location = new Point(10, 100),
                Size = new Size(1150, 70),
                BorderStyle = BorderStyle.FixedSingle
            };
            this.Controls.Add(pnlSearch);

            // 主面板 (包含数据表格和员工信息)
            pnlMain = new Panel
            {
                Location = new Point(10, 180),
                Size = new Size(1150, 400)
            };
            this.Controls.Add(pnlMain);

            // 分页面板 (主面板下方)
            pnlPagination = new Panel
            {
                Location = new Point(10, 590),
                Size = new Size(1150, 50),
                BorderStyle = BorderStyle.FixedSingle
            };
            this.Controls.Add(pnlPagination);

            // 按钮面板 (底部)
            pnlButtons = new Panel
            {
                Location = new Point(10, 650),
                Size = new Size(1150, 100),
                BorderStyle = BorderStyle.FixedSingle
            };
            this.Controls.Add(pnlButtons);
        }

        /// <summary>
        /// 初始化DataGridView
        /// </summary>
        private void InitializeDataGridView()
        {
            dgvEmployee = new DataGridView
            {
                Location = new Point(10, 10),
                Size = new Size(700, 380),
                AllowUserToAddRows = false,
                AllowUserToDeleteRows = false,
                AllowUserToOrderColumns = false,
                ReadOnly = true,
                MultiSelect = false,
                SelectionMode = DataGridViewSelectionMode.FullRowSelect,
                RowHeadersVisible = false,
                AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill,
                ScrollBars = ScrollBars.Vertical,
                BorderStyle = BorderStyle.FixedSingle
            };

            // 添加列
            CreateDataGridViewColumns();
            pnlMain.Controls.Add(dgvEmployee);

            // 绑定事件
            dgvEmployee.SelectionChanged += OnRowSelectedShowText;
            dgvEmployee.MouseDown += OnDataGridViewMouseDown;
        }

        /// <summary>
        /// 创建DataGridView列
        /// </summary>
        private void CreateDataGridViewColumns()
        {
            dgvEmployee.Columns.Clear();

            string[] columns = {
                "员工ID", "员工姓名", "员工性别", "员工年龄", 
                "所属部门", "入职时间", "员工密码", "部门负责人", "部门密码"
            };

            string[] properties = {
                "员工ID", "员工姓名", "员工性别", "员工年龄", 
                "所属部门", "入职时间", "员工密码", "部门负责人", "部门密码"
            };

            int[] widths = { 80, 120, 70, 70, 150, 100, 100, 120, 100 };

            for (int i = 0; i < columns.Length; i++)
            {
                var column = new DataGridViewTextBoxColumn
                {
                    HeaderText = columns[i],
                    DataPropertyName = properties[i],
                    Name = properties[i],
                    Width = widths[i],
                    ReadOnly = true
                };

                if (properties[i] == "入职时间")
                {
                    column.DefaultCellStyle.Format = "yyyy-MM-dd";
                }

                dgvEmployee.Columns.Add(column);
            }
        }

        /// <summary>
        /// 初始化员工信息面板
        /// </summary>
        private void InitializeEmployeeInfoPanel()
        {
            gbEmployeeInfo = new GroupBox
            {
                Text = "员工信息详情",
                Location = new Point(720, 10),
                Size = new Size(420, 380),
                Font = new Font("微软雅黑", 10, FontStyle.Bold)
            };

            CreateEmployeeInfoControls();
            pnlMain.Controls.Add(gbEmployeeInfo);
        }

        /// <summary>
        /// 创建员工信息显示控件
        /// </summary>
        private void CreateEmployeeInfoControls()
        {
            string[] labels = {
                "员工ID:", "员工姓名:", "员工性别:", "员工年龄:",
                "所属部门:", "入职时间:", "员工密码:", "部门负责人:", "部门密码:"
            };

            int startY = 30;
            int labelWidth = 100;
            int valueWidth = 280;
            int rowHeight = 35;

            for (int i = 0; i < labels.Length; i++)
            {
                // 标签
                Label lbl = new Label
                {
                    Text = labels[i],
                    Location = new Point(20, startY + i * rowHeight),
                    Size = new Size(labelWidth, 25),
                    TextAlign = ContentAlignment.MiddleRight,
                    Font = new Font("微软雅黑", 9, FontStyle.Bold)
                };

                // 值显示标签
                Label lblValue = new Label
                {
                    Name = "lbl" + labels[i].Replace(":", ""),
                    Location = new Point(labelWidth + 25, startY + i * rowHeight),
                    Size = new Size(valueWidth, 25),
                    BorderStyle = BorderStyle.FixedSingle,
                    TextAlign = ContentAlignment.MiddleLeft,
                    Font = new Font("微软雅黑", 9)
                };

                gbEmployeeInfo.Controls.Add(lbl);
                gbEmployeeInfo.Controls.Add(lblValue);
            }
        }

        /// <summary>
        /// 初始化分页控件
        /// </summary>
        private void InitializePaginationControls()
        {
            // 分页信息标签
            lblPageInfo = new Label
            {
                Location = new Point(10, 15),
                Size = new Size(300, 20),
                Text = "第 0-0 条,共 0 条",
                ForeColor = Color.Blue,
                Font = new Font("微软雅黑", 9)
            };
            pnlPagination.Controls.Add(lblPageInfo);

            // 首页按钮
            btnFirstPage = new Button
            {
                Text = "首页",
                Location = new Point(320, 10),
                Size = new Size(60, 30),
                Enabled = false
            };
            btnFirstPage.Click += BtnFirstPage_Click;
            pnlPagination.Controls.Add(btnFirstPage);

            // 上一页按钮
            btnPreviousPage = new Button
            {
                Text = "上一页",
                Location = new Point(390, 10),
                Size = new Size(60, 30),
                Enabled = false
            };
            btnPreviousPage.Click += BtnPreviousPage_Click;
            pnlPagination.Controls.Add(btnPreviousPage);

            // 页码输入
            txtPageNumber = new TextBox
            {
                Location = new Point(460, 10),
                Size = new Size(50, 30),
                Text = "1",
                TextAlign = HorizontalAlignment.Center
            };
            pnlPagination.Controls.Add(txtPageNumber);

            // 跳转按钮
            btnGoToPage = new Button
            {
                Text = "跳转",
                Location = new Point(520, 10),
                Size = new Size(60, 30)
            };
            btnGoToPage.Click += BtnGoToPage_Click;
            pnlPagination.Controls.Add(btnGoToPage);

            // 下一页按钮
            btnNextPage = new Button
            {
                Text = "下一页",
                Location = new Point(590, 10),
                Size = new Size(60, 30),
                Enabled = false
            };
            btnNextPage.Click += BtnNextPage_Click;
            pnlPagination.Controls.Add(btnNextPage);

            // 末页按钮
            btnLastPage = new Button
            {
                Text = "末页",
                Location = new Point(660, 10),
                Size = new Size(60, 30),
                Enabled = false
            };
            btnLastPage.Click += BtnLastPage_Click;
            pnlPagination.Controls.Add(btnLastPage);
        }

        /// <summary>
        /// 初始化搜索控件
        /// </summary>
        private void InitializeSearchControls()
        {
            // 员工姓名搜索
            Label lblEmpName = new Label
            {
                Text = "员工姓名:",
                Location = new Point(20, 20),
                Size = new Size(80, 25)
            };
            pnlSearch.Controls.Add(lblEmpName);

            cmbEmployeeName = new ComboBox
            {
                Location = new Point(100, 20),
                Size = new Size(150, 25),
                DropDownStyle = ComboBoxStyle.DropDown
            };
            pnlSearch.Controls.Add(cmbEmployeeName);

            // 部门名称搜索
            Label lblDepartment = new Label
            {
                Text = "所属部门:",
                Location = new Point(270, 20),
                Size = new Size(80, 25)
            };
            pnlSearch.Controls.Add(lblDepartment);

            cmbDepartment = new ComboBox
            {
                Location = new Point(350, 20),
                Size = new Size(150, 25),
                DropDownStyle = ComboBoxStyle.DropDown
            };
            pnlSearch.Controls.Add(cmbDepartment);

            // 部门负责人搜索
            Label lblManager = new Label
            {
                Text = "部门负责人:",
                Location = new Point(520, 20),
                Size = new Size(80, 25)
            };
            pnlSearch.Controls.Add(lblManager);

            cmbManager = new ComboBox
            {
                Location = new Point(600, 20),
                Size = new Size(150, 25),
                DropDownStyle = ComboBoxStyle.DropDown
            };
            pnlSearch.Controls.Add(cmbManager);

            // 搜索按钮
            btnSearch = new Button
            {
                Text = "搜索",
                Location = new Point(770, 20),
                Size = new Size(80, 25),
                BackColor = Color.LightGreen
            };
            btnSearch.Click += BtnSearch_Click;
            pnlSearch.Controls.Add(btnSearch);
        }

        /// <summary>
        /// 初始化按钮区域
        /// </summary>
        private void CreateButtonSection()
        {
            // 新增员工按钮
            btnAddEmployee = new Button
            {
                Text = "新增员工",
                Location = new Point(20, 30),
                Size = new Size(100, 40),
                BackColor = Color.LightSkyBlue
            };
            btnAddEmployee.Click += BtnAddEmployee_Click;
            pnlButtons.Controls.Add(btnAddEmployee);

            // 新增部门按钮
            btnAddDepartment = new Button
            {
                Text = "新增部门",
                Location = new Point(140, 30),
                Size = new Size(100, 40),
                BackColor = Color.LightSkyBlue
            };
            btnAddDepartment.Click += BtnAddDepartment_Click;
            pnlButtons.Controls.Add(btnAddDepartment);

            // 刷新按钮
            btnRefresh = new Button
            {
                Text = "刷新",
                Location = new Point(260, 30),
                Size = new Size(100, 40)
            };
            btnRefresh.Click += BtnRefresh_Click;
            pnlButtons.Controls.Add(btnRefresh);

            // 导出按钮
            btnExport = new Button
            {
                Text = "导出Excel",
                Location = new Point(380, 30),
                Size = new Size(100, 40),
                BackColor = Color.LightGoldenrodYellow
            };
            btnExport.Click += BtnExport_Click;
            pnlButtons.Controls.Add(btnExport);

            // 退出按钮
            btnExit = new Button
            {
                Text = "退出系统",
                Location = new Point(500, 30),
                Size = new Size(100, 40),
                BackColor = Color.LightCoral
            };
            btnExit.Click += BtnExit_Click;
            pnlButtons.Controls.Add(btnExit);
        }

        /// <summary>
        /// 初始化年龄列表
        /// </summary>
        private void InitAgeList()
        {
            _ageList.Clear();
            for (int i = Constants.MinAge; i <= Constants.MaxAge; i++)
                _ageList.Add(i);
        }

        #endregion

        #region 登录功能

        /// <summary>
        /// 创建登录界面
        /// </summary>
        private void CreateLoginControls()
        {
            // 用户名
            Label lblUsername = new Label
            {
                Text = "用户名:",
                Location = new Point(20, 25),
                Size = new Size(70, 25)
            };
            pnlLogin.Controls.Add(lblUsername);

            txtUsername = new TextBox
            {
                Location = new Point(95, 25),
                Size = new Size(150, 25),
                Text = "admin"
            };
            pnlLogin.Controls.Add(txtUsername);

            // 密码
            Label lblPassword = new Label
            {
                Text = "密码:",
                Location = new Point(270, 25),
                Size = new Size(70, 25)
            };
            pnlLogin.Controls.Add(lblPassword);

            txtPassword = new TextBox
            {
                Location = new Point(345, 25),
                Size = new Size(150, 25),
                PasswordChar = '*'
            };
            pnlLogin.Controls.Add(txtPassword);

            // 记住密码
            chkRemember = new CheckBox
            {
                Text = "记住密码",
                Location = new Point(510, 25),
                Size = new Size(100, 25),
                Checked = true
            };
            pnlLogin.Controls.Add(chkRemember);

            // 登录按钮
            btnLogin = new Button
            {
                Text = "登录",
                Location = new Point(620, 20),
                Size = new Size(100, 35),
                BackColor = Color.LightGreen,
                Font = new Font("微软雅黑", 10, FontStyle.Bold)
            };
            btnLogin.Click += BtnLogin_Click;
            pnlLogin.Controls.Add(btnLogin);
        }

        /// <summary>
        /// 登录按钮点击事件
        /// </summary>
        private async void BtnLogin_Click(object sender, EventArgs e)
        {
            string account = txtUsername.Text.Trim();
            string password = txtPassword.Text.Trim();

            if (string.IsNullOrEmpty(account))
            {
                MessageBox.Show("请输入用户名!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtUsername.Focus();
                return;
            }

            if (string.IsNullOrEmpty(password))
            {
                MessageBox.Show("请输入密码!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtPassword.Focus();
                return;
            }

            try
            {
                Cursor = Cursors.WaitCursor;
                bool isValid = await _loginService.ValidateLoginAsync(account, password);

                if (isValid)
                {
                    LoginSuccess(account, password);
                }
                else
                {
                    MessageBox.Show("用户名或密码错误!", "登录失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    txtPassword.Text = "";
                    txtPassword.Focus();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"登录失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                Cursor = Cursors.Default;
            }
        }

        /// <summary>
        /// 登录成功处理
        /// </summary>
        private void LoginSuccess(string account, string password)
        {
            MessageBox.Show("登录成功!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
            
            // 保存记住的密码
            SaveRememberedPassword(account, password);
            
            // 设置登录状态
            _isLoggedIn = true;
            
            // 禁用登录相关控件
            txtUsername.Enabled = false;
            txtPassword.Enabled = false;
            btnLogin.Enabled = false;
            
            // 显示数据
            ShowAllData();
        }

        /// <summary>
        /// 加载记住的密码
        /// </summary>
        private void LoadRememberedPassword()
        {
            try
            {
                // 这里需要添加实际的密码加载逻辑
                // 可以使用配置文件或数据库存储记住的密码
                if (chkRemember != null && chkRemember.Checked)
                {
                    // 示例:从设置中加载
                    txtUsername.Text = Properties.Settings.Default.LastUsername ?? "admin";
                    txtPassword.Text = Properties.Settings.Default.LastPassword ?? "";
                }
            }
            catch
            {
                // 忽略加载错误
            }
        }

        /// <summary>
        /// 保存记住的密码
        /// </summary>
        private void SaveRememberedPassword(string account, string password)
        {
            try
            {
                if (chkRemember.Checked)
                {
                    Properties.Settings.Default.LastUsername = account;
                    Properties.Settings.Default.LastPassword = password;
                    Properties.Settings.Default.Save();
                }
            }
            catch
            {
                // 忽略保存错误
            }
        }

        #endregion

        #region 数据加载和显示

        /// <summary>
        /// 显示所有数据
        /// </summary>
        private async void ShowAllData()
        {
            try
            {
                Cursor = Cursors.WaitCursor;
                await LoadFirstPage();
                await InitializeSearchDropdowns();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"加载数据失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                Cursor = Cursors.Default;
            }
        }

        /// <summary>
        /// 加载第一页数据
        /// </summary>
        private async Task LoadFirstPage()
        {
            _currentPage = 1;
            _searchMode = false;
            _searchConditions = "";
            await LoadPageData();
        }

        /// <summary>
        /// 加载当前页数据
        /// </summary>
        private async Task LoadPageData()
        {
            try
            {
                var result = await _paginationService.GetPagedDataAsync(
                    _searchConditions, _orderByColumn, _currentPage);

                dgvEmployee.DataSource = result.DataTable;
                _totalRecords = result.TotalRecords;
                _totalPages = result.TotalPages;

                UpdatePaginationInfo(result);

                if (dgvEmployee.Rows.Count > 0)
                {
                    dgvEmployee.Rows[0].Selected = true;
                    OnRowSelectedShowText(null, EventArgs.Empty);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"加载数据失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 初始化搜索下拉框
        /// </summary>
        private async Task InitializeSearchDropdowns()
        {
            try
            {
                // 员工姓名下拉框
                var empNames = await _employeeService.InitializeEmployeeComboBoxAsync();
                cmbEmployeeName.DataSource = empNames;
                cmbEmployeeName.SelectedIndex = -1;

                // 部门下拉框
                _departmentTable = await _employeeService.GetDepartmentDataForComboBoxAsync();
                cmbDepartment.DataSource = _departmentTable.Copy();
                cmbDepartment.DisplayMember = "DepName";
                cmbDepartment.ValueMember = "DepID";
                cmbDepartment.SelectedIndex = -1;

                // 部门负责人下拉框
                var managers = await _employeeService.GetDepartmentManagersForComboBoxAsync();
                cmbManager.DataSource = managers;
                cmbManager.SelectedIndex = -1;
            }
            catch (Exception ex)
            {
                MessageBox.Show($"初始化搜索下拉框失败:{ex.Message}", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        /// <summary>
        /// 更新分页信息
        /// </summary>
        private void UpdatePaginationInfo(PaginationResult result)
        {
            string searchModeInfo = _searchMode ? "(搜索模式)" : "";
            
            lblPageInfo.Text = $"第 {result.StartRecord}-{result.EndRecord} 条,共 {result.TotalRecords} 条,第 {result.CurrentPage}/{result.TotalPages} 页{searchModeInfo}";
            
            txtPageNumber.Text = _currentPage.ToString();

            // 更新按钮状态
            btnFirstPage.Enabled = _currentPage > 1;
            btnPreviousPage.Enabled = _currentPage > 1;
            btnNextPage.Enabled = _currentPage < _totalPages;
            btnLastPage.Enabled = _currentPage < _totalPages;
        }

        /// <summary>
        /// 隐藏所有数据
        /// </summary>
        private void HideAllData()
        {
            dgvEmployee.DataSource = null;
            ClearEmployeeInfo();
            _isLoggedIn = false;
            _currentPage = 1;
        }

        /// <summary>
        /// 清空员工信息显示
        /// </summary>
        private void ClearEmployeeInfo()
        {
            foreach (Control control in gbEmployeeInfo.Controls)
            {
                if (control is Label label && label.Name.StartsWith("lbl"))
                {
                    label.Text = "";
                }
            }
        }

        #endregion

        #region 事件处理

        /// <summary>
        /// DataGridView行选中事件
        /// </summary>
        private void OnRowSelectedShowText(object sender, EventArgs e)
        {
            if (!_isLoggedIn || dgvEmployee.SelectedRows.Count == 0)
            {
                ClearEmployeeInfo();
                return;
            }

            DataGridViewRow selectedRow = dgvEmployee.SelectedRows[0];
            UpdateEmployeeInfo(selectedRow);
        }

        /// <summary>
        /// 更新员工信息显示
        /// </summary>
        private void UpdateEmployeeInfo(DataGridViewRow row)
        {
            Dictionary<string, string> fieldMapping = new Dictionary<string, string>
            {
                { "员工ID", "员工ID" },
                { "员工姓名", "员工姓名" },
                { "员工性别", "员工性别" },
                { "员工年龄", "员工年龄" },
                { "所属部门", "所属部门" },
                { "入职时间", "入职时间" },
                { "员工密码", "员工密码" },
                { "部门负责人", "部门负责人" },
                { "部门密码", "部门密码" }
            };

            foreach (var mapping in fieldMapping)
            {
                Label label = gbEmployeeInfo.Controls["lbl" + mapping.Key] as Label;
                if (label != null && row.Cells[mapping.Value].Value != null)
                {
                    string value = row.Cells[mapping.Value].Value.ToString();
                    
                    // 特殊处理日期格式
                    if (mapping.Key == "入职时间" && DateTime.TryParse(value, out DateTime date))
                    {
                        value = date.ToString("yyyy-MM-dd");
                    }
                    
                    label.Text = value;
                }
            }
        }

        /// <summary>
        /// DataGridView鼠标按下事件(右键菜单)
        /// </summary>
        private void OnDataGridViewMouseDown(object sender, MouseEventArgs e)
        {
            if (!_isLoggedIn) return;

            if (e.Button == MouseButtons.Right)
            {
                var hitTest = dgvEmployee.HitTest(e.X, e.Y);
                if (hitTest.RowIndex >= 0 && hitTest.RowIndex < dgvEmployee.Rows.Count)
                {
                    dgvEmployee.ClearSelection();
                    dgvEmployee.Rows[hitTest.RowIndex].Selected = true;
                    _selectedRow = dgvEmployee.Rows[hitTest.RowIndex];
                    
                    // 显示右键菜单
                    ShowContextMenu(e.Location);
                }
            }
        }

        /// <summary>
        /// 显示右键菜单
        /// </summary>
        private void ShowContextMenu(Point location)
        {
            ContextMenuStrip contextMenu = new ContextMenuStrip();

            ToolStripMenuItem editEmployee = new ToolStripMenuItem("编辑员工");
            editEmployee.Click += OnEditEmployeeClick;
            contextMenu.Items.Add(editEmployee);

            ToolStripMenuItem editDepartment = new ToolStripMenuItem("编辑部门");
            editDepartment.Click += OnEditDepartmentClick;
            contextMenu.Items.Add(editDepartment);

            contextMenu.Items.Add(new ToolStripSeparator());

            ToolStripMenuItem deleteEmployee = new ToolStripMenuItem("删除员工");
            deleteEmployee.Click += OnDeleteEmployeeClick;
            contextMenu.Items.Add(deleteEmployee);

            ToolStripMenuItem deleteDepartment = new ToolStripMenuItem("删除部门");
            deleteDepartment.Click += OnDeleteDepartmentClick;
            contextMenu.Items.Add(deleteDepartment);

            ToolStripMenuItem deleteRow = new ToolStripMenuItem("删除整行");
            deleteRow.Click += OnDeleteRowClick;
            contextMenu.Items.Add(deleteRow);

            contextMenu.Show(dgvEmployee, location);
        }

        #endregion

        #region 分页按钮事件

        private async void BtnFirstPage_Click(object sender, EventArgs e)
        {
            if (!_isLoggedIn) return;
            _currentPage = 1;
            await LoadPageData();
        }

        private async void BtnPreviousPage_Click(object sender, EventArgs e)
        {
            if (!_isLoggedIn) return;
            if (_currentPage > 1)
            {
                _currentPage--;
                await LoadPageData();
            }
        }

        private async void BtnNextPage_Click(object sender, EventArgs e)
        {
            if (!_isLoggedIn) return;
            if (_currentPage < _totalPages)
            {
                _currentPage++;
                await LoadPageData();
            }
        }

        private async void BtnLastPage_Click(object sender, EventArgs e)
        {
            if (!_isLoggedIn) return;
            _currentPage = _totalPages;
            await LoadPageData();
        }

        private async void BtnGoToPage_Click(object sender, EventArgs e)
        {
            if (!_isLoggedIn) return;

            if (int.TryParse(txtPageNumber.Text, out int page) && page >= 1 && page <= _totalPages)
            {
                _currentPage = page;
                await LoadPageData();
            }
            else
            {
                MessageBox.Show($"请输入有效的页码 (1-{_totalPages})", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtPageNumber.Focus();
                txtPageNumber.SelectAll();
            }
        }

        #endregion

        #region 搜索功能

        private async void BtnSearch_Click(object sender, EventArgs e)
        {
            if (!_isLoggedIn)
            {
                MessageBox.Show("请先登录!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            try
            {
                string empName = cmbEmployeeName.Text.Trim();
                string deptName = cmbDepartment.Text.Trim();
                string manager = cmbManager.Text.Trim();

                _searchConditions = _paginationService.BuildSearchConditions(empName, deptName, manager);
                _searchMode = !string.IsNullOrEmpty(_searchConditions);
                _currentPage = 1;

                await LoadPageData();

                if (_searchMode)
                {
                    MessageBox.Show($"找到 {_totalRecords} 条匹配记录", "搜索完成", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }

                // 清空搜索框
                cmbEmployeeName.Text = "";
                cmbDepartment.Text = "";
                cmbManager.Text = "";
            }
            catch (Exception ex)
            {
                MessageBox.Show($"搜索失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        #endregion

        #region 主要功能按钮

        private void BtnAddEmployee_Click(object sender, EventArgs e)
        {
            if (!_isLoggedIn)
            {
                MessageBox.Show("请先登录!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            ShowAddEmployeeForm();
        }

        private void ShowAddEmployeeForm()
        {
            // 创建新增员工窗体
            AddEmployeeForm form = new AddEmployeeForm(_employeeService, _departmentTable);
            form.EmployeeAdded += async (s, args) =>
            {
                MessageBox.Show("员工添加成功!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                await LoadPageData();
            };
            form.ShowDialog();
        }

        private void BtnAddDepartment_Click(object sender, EventArgs e)
        {
            if (!_isLoggedIn)
            {
                MessageBox.Show("请先登录!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            ShowAddDepartmentForm();
        }

        private async void ShowAddDepartmentForm()
        {
            AddDepartmentForm form = new AddDepartmentForm(_departmentService);
            if (form.ShowDialog() == DialogResult.OK)
            {
                MessageBox.Show("部门添加成功!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                await InitializeSearchDropdowns();
                await LoadPageData();
            }
        }

        private async void BtnRefresh_Click(object sender, EventArgs e)
        {
            if (!_isLoggedIn)
            {
                MessageBox.Show("请先登录!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            try
            {
                Cursor = Cursors.WaitCursor;
                await LoadPageData();
                MessageBox.Show("数据已刷新!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"刷新失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                Cursor = Cursors.Default;
            }
        }

        private async void BtnExport_Click(object sender, EventArgs e)
        {
            if (!_isLoggedIn)
            {
                MessageBox.Show("请先登录!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            if (dgvEmployee.Rows.Count == 0)
            {
                MessageBox.Show("没有可导出的数据!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            using (SaveFileDialog saveFileDialog = new SaveFileDialog())
            {
                saveFileDialog.Filter = "Excel文件 (*.xlsx)|*.xlsx";
                saveFileDialog.Title = "导出员工数据";
                saveFileDialog.FileName = $"员工数据_{DateTime.Now:yyyyMMddHHmmss}.xlsx";

                if (saveFileDialog.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        Cursor = Cursors.WaitCursor;
                        string filePath = await _exportService.ExportEmployeesToExcelAsync(saveFileDialog.FileName, dgvEmployee);
                        
                        MessageBox.Show($"数据已成功导出到:\n{filePath}", "导出成功", 
                            MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show($"导出失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    finally
                    {
                        Cursor = Cursors.Default;
                    }
                }
            }
        }

        private void BtnExit_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("确定要退出系统吗?", "确认退出", 
                MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                Application.Exit();
            }
        }

        #endregion

        #region 右键菜单事件处理

        private void OnEditEmployeeClick(object sender, EventArgs e)
        {
            if (_selectedRow == null) return;
            ShowEditEmployeeForm();
        }

        private void ShowEditEmployeeForm()
        {
            int empId = Convert.ToInt32(_selectedRow.Cells["员工ID"].Value);
            string empName = _selectedRow.Cells["员工姓名"].Value?.ToString();
            string gender = _selectedRow.Cells["员工性别"].Value?.ToString();
            int age = Convert.ToInt32(_selectedRow.Cells["员工年龄"].Value);
            string deptName = _selectedRow.Cells["所属部门"].Value?.ToString();
            DateTime hireDate = Convert.ToDateTime(_selectedRow.Cells["入职时间"].Value);
            string password = _selectedRow.Cells["员工密码"].Value?.ToString();

            EditEmployeeForm form = new EditEmployeeForm(
                empId, empName, gender, age, deptName, hireDate, password, 
                _employeeService, _departmentTable, _ageList);
            
            form.EmployeeUpdated += async (s, args) =>
            {
                MessageBox.Show("员工信息更新成功!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                await LoadPageData();
            };
            
            form.ShowDialog();
        }

        private void OnEditDepartmentClick(object sender, EventArgs e)
        {
            if (_selectedRow == null) return;
            ShowEditDepartmentForm();
        }

        private void ShowEditDepartmentForm()
        {
            string deptName = _selectedRow.Cells["所属部门"].Value?.ToString();
            string manager = _selectedRow.Cells["部门负责人"].Value?.ToString();
            string password = _selectedRow.Cells["部门密码"].Value?.ToString();

            EditDepartmentForm form = new EditDepartmentForm(
                deptName, manager, password, _departmentService, _departmentTable);
            
            form.DepartmentUpdated += async (s, args) =>
            {
                MessageBox.Show("部门信息更新成功!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                await LoadPageData();
                await InitializeSearchDropdowns();
            };
            
            form.ShowDialog();
        }

        private void OnDeleteEmployeeClick(object sender, EventArgs e)
        {
            if (_selectedRow == null) return;
            
            string empName = _selectedRow.Cells["员工姓名"].Value?.ToString();
            if (MessageBox.Show($"确定要删除员工【{empName}】吗?", "确认删除", 
                MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
            {
                DeleteEmployee();
            }
        }

        private async void DeleteEmployee()
        {
            try
            {
                int empId = Convert.ToInt32(_selectedRow.Cells["员工ID"].Value);
                bool success = await _employeeService.DeleteEmployeeAsync(empId);
                
                if (success)
                {
                    MessageBox.Show("员工删除成功!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    await LoadPageData();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"删除失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void OnDeleteDepartmentClick(object sender, EventArgs e)
        {
            if (_selectedRow == null) return;
            
            string deptName = _selectedRow.Cells["所属部门"].Value?.ToString();
            if (MessageBox.Show($"确定要删除部门【{deptName}】吗?\n删除前请先转移部门员工。", "确认删除", 
                MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
            {
                ShowDeleteDepartmentForm();
            }
        }

        private void ShowDeleteDepartmentForm()
        {
            string deptName = _selectedRow.Cells["所属部门"].Value?.ToString();
            DeleteDepartmentForm form = new DeleteDepartmentForm(deptName, _departmentService, _departmentTable);
            form.DepartmentDeleted += async (s, args) =>
            {
                MessageBox.Show("部门删除成功!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                await LoadPageData();
                await InitializeSearchDropdowns();
            };
            form.ShowDialog();
        }

        private void OnDeleteRowClick(object sender, EventArgs e)
        {
            if (_selectedRow == null) return;
            
            string empName = _selectedRow.Cells["员工姓名"].Value?.ToString();
            string deptName = _selectedRow.Cells["所属部门"].Value?.ToString();
            
            if (MessageBox.Show($"确定要删除员工【{empName}】(部门:{deptName})吗?", "确认删除", 
                MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
            {
                DeleteEmployee();
            }
        }

        #endregion

        /// <summary>
        /// 清理资源
        /// </summary>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                // 清理事件绑定
                if (dgvEmployee != null)
                {
                    dgvEmployee.SelectionChanged -= OnRowSelectedShowText;
                    dgvEmployee.MouseDown -= OnDataGridViewMouseDown;
                }
                
                if (btnLogin != null)
                    btnLogin.Click -= BtnLogin_Click;
                    
                // 清理其他事件绑定...
            }
            base.Dispose(disposing);
        }
    }
}

2. Program.cs (应用程序入口)

csharp 复制代码
using System;
using System.Windows.Forms;

namespace PresentationLayer
{
    internal static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

3. 子窗体类

AddEmployeeForm.cs (新增员工窗体)

csharp 复制代码
using BusinessLogicLayer;
using System;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;

namespace PresentationLayer
{
    public partial class AddEmployeeForm : Form
    {
        private readonly EmployeeService _employeeService;
        private readonly DataTable _departmentTable;
        private readonly ComboBox cmbGender;
        private readonly ComboBox cmbAge;
        private readonly ComboBox cmbDepartment;
        private readonly TextBox txtName;
        private readonly DateTimePicker dtpHireDate;
        private readonly TextBox txtPassword;

        public event EventHandler EmployeeAdded;

        public AddEmployeeForm(EmployeeService employeeService, DataTable departmentTable)
        {
            _employeeService = employeeService;
            _departmentTable = departmentTable;
            
            InitializeForm();
            InitializeControls();
        }

        private void InitializeForm()
        {
            this.Text = "新增员工";
            this.Size = new Size(400, 400);
            this.StartPosition = FormStartPosition.CenterParent;
            this.FormBorderStyle = FormBorderStyle.FixedDialog;
            this.MaximizeBox = false;
            this.MinimizeBox = false;
        }

        private void InitializeControls()
        {
            int y = 20;
            int labelWidth = 80;
            int controlWidth = 200;

            // 员工姓名
            Label lblName = new Label
            {
                Text = "员工姓名:",
                Location = new Point(30, y),
                Size = new Size(labelWidth, 25)
            };
            this.Controls.Add(lblName);

            txtName = new TextBox
            {
                Location = new Point(120, y),
                Size = new Size(controlWidth, 25)
            };
            this.Controls.Add(txtName);
            y += 40;

            // 员工性别
            Label lblGender = new Label
            {
                Text = "员工性别:",
                Location = new Point(30, y),
                Size = new Size(labelWidth, 25)
            };
            this.Controls.Add(lblGender);

            cmbGender = new ComboBox
            {
                Location = new Point(120, y),
                Size = new Size(controlWidth, 25),
                DropDownStyle = ComboBoxStyle.DropDownList
            };
            cmbGender.Items.AddRange(Constants.Genders);
            if (cmbGender.Items.Count > 0)
                cmbGender.SelectedIndex = 0;
            this.Controls.Add(cmbGender);
            y += 40;

            // 员工年龄
            Label lblAge = new Label
            {
                Text = "员工年龄:",
                Location = new Point(30, y),
                Size = new Size(labelWidth, 25)
            };
            this.Controls.Add(lblAge);

            cmbAge = new ComboBox
            {
                Location = new Point(120, y),
                Size = new Size(controlWidth, 25),
                DropDownStyle = ComboBoxStyle.DropDownList
            };
            for (int i = Constants.MinAge; i <= Constants.MaxAge; i++)
                cmbAge.Items.Add(i);
            if (cmbAge.Items.Count > 0)
                cmbAge.SelectedIndex = 0;
            this.Controls.Add(cmbAge);
            y += 40;

            // 所属部门
            Label lblDepartment = new Label
            {
                Text = "所属部门:",
                Location = new Point(30, y),
                Size = new Size(labelWidth, 25)
            };
            this.Controls.Add(lblDepartment);

            cmbDepartment = new ComboBox
            {
                Location = new Point(120, y),
                Size = new Size(controlWidth, 25),
                DropDownStyle = ComboBoxStyle.DropDownList
            };
            if (_departmentTable != null)
            {
                cmbDepartment.DisplayMember = "DepName";
                cmbDepartment.ValueMember = "DepID";
                cmbDepartment.DataSource = _departmentTable;
            }
            this.Controls.Add(cmbDepartment);
            y += 40;

            // 入职时间
            Label lblHireDate = new Label
            {
                Text = "入职时间:",
                Location = new Point(30, y),
                Size = new Size(labelWidth, 25)
            };
            this.Controls.Add(lblHireDate);

            dtpHireDate = new DateTimePicker
            {
                Location = new Point(120, y),
                Size = new Size(controlWidth, 25),
                Format = DateTimePickerFormat.Custom,
                CustomFormat = "yyyy-MM-dd",
                Value = DateTime.Now
            };
            this.Controls.Add(dtpHireDate);
            y += 40;

            // 员工密码
            Label lblPassword = new Label
            {
                Text = "员工密码:",
                Location = new Point(30, y),
                Size = new Size(labelWidth, 25)
            };
            this.Controls.Add(lblPassword);

            txtPassword = new TextBox
            {
                Location = new Point(120, y),
                Size = new Size(controlWidth, 25),
                Text = Constants.DefaultEmployeePassword
            };
            this.Controls.Add(txtPassword);
            y += 50;

            // 按钮
            Button btnAdd = new Button
            {
                Text = "添加",
                Location = new Point(80, y),
                Size = new Size(100, 30),
                BackColor = Color.LightGreen
            };
            btnAdd.Click += BtnAdd_Click;
            this.Controls.Add(btnAdd);

            Button btnCancel = new Button
            {
                Text = "取消",
                Location = new Point(200, y),
                Size = new Size(100, 30)
            };
            btnCancel.Click += (s, e) => this.Close();
            this.Controls.Add(btnCancel);
        }

        private async void BtnAdd_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(txtName.Text))
            {
                MessageBox.Show("请输入员工姓名!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtName.Focus();
                return;
            }

            if (cmbGender.SelectedItem == null || cmbAge.SelectedItem == null || cmbDepartment.SelectedValue == null)
            {
                MessageBox.Show("请完善所有必填项!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            try
            {
                int depId = (int)cmbDepartment.SelectedValue;
                bool success = await _employeeService.AddEmployeeAsync(
                    txtName.Text.Trim(),
                    cmbGender.SelectedItem.ToString(),
                    (int)cmbAge.SelectedItem,
                    depId,
                    dtpHireDate.Value,
                    txtPassword.Text.Trim());

                if (success)
                {
                    EmployeeAdded?.Invoke(this, EventArgs.Empty);
                    this.Close();
                }
                else
                {
                    MessageBox.Show("添加员工失败!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"添加失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }
}

EditEmployeeForm.cs (编辑员工窗体)

csharp 复制代码
using BusinessLogicLayer;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Windows.Forms;

namespace PresentationLayer
{
    public partial class EditEmployeeForm : Form
    {
        private readonly int _empId;
        private readonly EmployeeService _employeeService;
        private readonly DataTable _departmentTable;
        private readonly List<int> _ageList;
        
        private readonly ComboBox cmbGender;
        private readonly ComboBox cmbAge;
        private readonly ComboBox cmbDepartment;
        private readonly TextBox txtName;
        private readonly DateTimePicker dtpHireDate;
        private readonly TextBox txtPassword;

        public event EventHandler EmployeeUpdated;

        public EditEmployeeForm(int empId, string empName, string gender, int age, 
                              string deptName, DateTime hireDate, string password,
                              EmployeeService employeeService, DataTable departmentTable, 
                              List<int> ageList)
        {
            _empId = empId;
            _employeeService = employeeService;
            _departmentTable = departmentTable;
            _ageList = ageList;

            InitializeForm();
            InitializeControls(empName, gender, age, deptName, hireDate, password);
        }

        private void InitializeForm()
        {
            this.Text = "编辑员工信息";
            this.Size = new Size(400, 400);
            this.StartPosition = FormStartPosition.CenterParent;
            this.FormBorderStyle = FormBorderStyle.FixedDialog;
            this.MaximizeBox = false;
            this.MinimizeBox = false;
        }

        private void InitializeControls(string empName, string gender, int age, 
                                       string deptName, DateTime hireDate, string password)
        {
            int y = 20;
            int labelWidth = 80;
            int controlWidth = 200;

            // 员工ID (只读)
            Label lblId = new Label
            {
                Text = "员工ID:",
                Location = new Point(30, y),
                Size = new Size(labelWidth, 25)
            };
            this.Controls.Add(lblId);

            Label lblIdValue = new Label
            {
                Text = _empId.ToString(),
                Location = new Point(120, y),
                Size = new Size(controlWidth, 25),
                BorderStyle = BorderStyle.FixedSingle
            };
            this.Controls.Add(lblIdValue);
            y += 40;

            // 员工姓名
            Label lblName = new Label
            {
                Text = "员工姓名:",
                Location = new Point(30, y),
                Size = new Size(labelWidth, 25)
            };
            this.Controls.Add(lblName);

            txtName = new TextBox
            {
                Location = new Point(120, y),
                Size = new Size(controlWidth, 25),
                Text = empName
            };
            this.Controls.Add(txtName);
            y += 40;

            // 员工性别
            Label lblGender = new Label
            {
                Text = "员工性别:",
                Location = new Point(30, y),
                Size = new Size(labelWidth, 25)
            };
            this.Controls.Add(lblGender);

            cmbGender = new ComboBox
            {
                Location = new Point(120, y),
                Size = new Size(controlWidth, 25),
                DropDownStyle = ComboBoxStyle.DropDownList
            };
            cmbGender.Items.AddRange(Constants.Genders);
            cmbGender.SelectedItem = gender;
            this.Controls.Add(cmbGender);
            y += 40;

            // 员工年龄
            Label lblAge = new Label
            {
                Text = "员工年龄:",
                Location = new Point(30, y),
                Size = new Size(labelWidth, 25)
            };
            this.Controls.Add(lblAge);

            cmbAge = new ComboBox
            {
                Location = new Point(120, y),
                Size = new Size(controlWidth, 25),
                DropDownStyle = ComboBoxStyle.DropDownList
            };
            cmbAge.Items.AddRange(_ageList.Cast<object>().ToArray());
            cmbAge.SelectedItem = age;
            this.Controls.Add(cmbAge);
            y += 40;

            // 所属部门
            Label lblDepartment = new Label
            {
                Text = "所属部门:",
                Location = new Point(30, y),
                Size = new Size(labelWidth, 25)
            };
            this.Controls.Add(lblDepartment);

            cmbDepartment = new ComboBox
            {
                Location = new Point(120, y),
                Size = new Size(controlWidth, 25),
                DropDownStyle = ComboBoxStyle.DropDownList
            };
            if (_departmentTable != null)
            {
                cmbDepartment.DisplayMember = "DepName";
                cmbDepartment.ValueMember = "DepID";
                cmbDepartment.DataSource = _departmentTable;
                
                // 设置选中值
                foreach (DataRow row in _departmentTable.Rows)
                {
                    if (row["DepName"].ToString() == deptName)
                    {
                        cmbDepartment.SelectedValue = row["DepID"];
                        break;
                    }
                }
            }
            this.Controls.Add(cmbDepartment);
            y += 40;

            // 入职时间
            Label lblHireDate = new Label
            {
                Text = "入职时间:",
                Location = new Point(30, y),
                Size = new Size(labelWidth, 25)
            };
            this.Controls.Add(lblHireDate);

            dtpHireDate = new DateTimePicker
            {
                Location = new Point(120, y),
                Size = new Size(controlWidth, 25),
                Format = DateTimePickerFormat.Custom,
                CustomFormat = "yyyy-MM-dd",
                Value = hireDate
            };
            this.Controls.Add(dtpHireDate);
            y += 40;

            // 员工密码
            Label lblPassword = new Label
            {
                Text = "员工密码:",
                Location = new Point(30, y),
                Size = new Size(labelWidth, 25)
            };
            this.Controls.Add(lblPassword);

            txtPassword = new TextBox
            {
                Location = new Point(120, y),
                Size = new Size(controlWidth, 25),
                Text = password
            };
            this.Controls.Add(txtPassword);
            y += 50;

            // 按钮
            Button btnUpdate = new Button
            {
                Text = "更新",
                Location = new Point(80, y),
                Size = new Size(100, 30),
                BackColor = Color.LightGreen
            };
            btnUpdate.Click += BtnUpdate_Click;
            this.Controls.Add(btnUpdate);

            Button btnCancel = new Button
            {
                Text = "取消",
                Location = new Point(200, y),
                Size = new Size(100, 30)
            };
            btnCancel.Click += (s, e) => this.Close();
            this.Controls.Add(btnCancel);
        }

        private async void BtnUpdate_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(txtName.Text))
            {
                MessageBox.Show("请输入员工姓名!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtName.Focus();
                return;
            }

            try
            {
                int depId = (int)cmbDepartment.SelectedValue;
                bool success = await _employeeService.UpdateEmployeeAsync(
                    _empId,
                    txtName.Text.Trim(),
                    cmbGender.SelectedItem.ToString(),
                    (int)cmbAge.SelectedItem,
                    depId,
                    dtpHireDate.Value,
                    txtPassword.Text.Trim());

                if (success)
                {
                    EmployeeUpdated?.Invoke(this, EventArgs.Empty);
                    this.Close();
                }
                else
                {
                    MessageBox.Show("更新员工信息失败!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"更新失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }
}

AddDepartmentForm.cs (新增部门窗体)

csharp 复制代码
using BusinessLogicLayer;
using System;
using System.Drawing;
using System.Windows.Forms;

namespace PresentationLayer
{
    public partial class AddDepartmentForm : Form
    {
        private readonly DepartmentService _departmentService;
        private readonly TextBox txtName;
        private readonly TextBox txtManager;
        private readonly TextBox txtPassword;
        private readonly TextBox txtDescription;

        public AddDepartmentForm(DepartmentService departmentService)
        {
            _departmentService = departmentService;
            
            InitializeForm();
            InitializeControls();
        }

        private void InitializeForm()
        {
            this.Text = "新增部门";
            this.Size = new Size(400, 350);
            this.StartPosition = FormStartPosition.CenterParent;
            this.FormBorderStyle = FormBorderStyle.FixedDialog;
            this.MaximizeBox = false;
            this.MinimizeBox = false;
        }

        private void InitializeControls()
        {
            int y = 20;
            int labelWidth = 80;
            int controlWidth = 200;

            // 部门名称
            Label lblName = new Label
            {
                Text = "部门名称:",
                Location = new Point(30, y),
                Size = new Size(labelWidth, 25)
            };
            this.Controls.Add(lblName);

            txtName = new TextBox
            {
                Location = new Point(120, y),
                Size = new Size(controlWidth, 25)
            };
            this.Controls.Add(txtName);
            y += 40;

            // 部门负责人
            Label lblManager = new Label
            {
                Text = "部门负责人:",
                Location = new Point(30, y),
                Size = new Size(labelWidth, 25)
            };
            this.Controls.Add(lblManager);

            txtManager = new TextBox
            {
                Location = new Point(120, y),
                Size = new Size(controlWidth, 25)
            };
            this.Controls.Add(txtManager);
            y += 40;

            // 部门密码
            Label lblPassword = new Label
            {
                Text = "部门密码:",
                Location = new Point(30, y),
                Size = new Size(labelWidth, 25)
            };
            this.Controls.Add(lblPassword);

            txtPassword = new TextBox
            {
                Location = new Point(120, y),
                Size = new Size(controlWidth, 25),
                Text = Constants.DefaultDepartmentPassword
            };
            this.Controls.Add(txtPassword);
            y += 40;

            // 部门描述
            Label lblDescription = new Label
            {
                Text = "部门描述:",
                Location = new Point(30, y),
                Size = new Size(labelWidth, 25)
            };
            this.Controls.Add(lblDescription);

            txtDescription = new TextBox
            {
                Location = new Point(120, y),
                Size = new Size(controlWidth, 60),
                Multiline = true
            };
            this.Controls.Add(txtDescription);
            y += 70;

            // 按钮
            Button btnAdd = new Button
            {
                Text = "添加",
                Location = new Point(80, y),
                Size = new Size(100, 30),
                BackColor = Color.LightGreen
            };
            btnAdd.Click += BtnAdd_Click;
            this.Controls.Add(btnAdd);

            Button btnCancel = new Button
            {
                Text = "取消",
                Location = new Point(200, y),
                Size = new Size(100, 30)
            };
            btnCancel.Click += (s, e) => this.Close();
            this.Controls.Add(btnCancel);
        }

        private async void BtnAdd_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(txtName.Text))
            {
                MessageBox.Show("请输入部门名称!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtName.Focus();
                return;
            }

            if (string.IsNullOrWhiteSpace(txtManager.Text))
            {
                MessageBox.Show("请输入部门负责人!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtManager.Focus();
                return;
            }

            try
            {
                bool success = await _departmentService.AddDepartmentAsync(
                    txtName.Text.Trim(),
                    txtDescription.Text.Trim(),
                    txtManager.Text.Trim(),
                    txtPassword.Text.Trim());

                if (success)
                {
                    this.DialogResult = DialogResult.OK;
                    this.Close();
                }
                else
                {
                    MessageBox.Show("添加部门失败!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"添加失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }
}

4. 使用说明

  1. 创建项目

    • 创建新的Windows Forms Application (.NET Framework)项目
    • 添加对BusinessLogicLayer、DataAccessLayer、Common项目的引用
  2. 添加NuGet包

    • Microsoft.Data.SqlClient
    • EPPlus
  3. 配置连接字符串

    • 在Common项目的AppSettings.cs中修改连接字符串
  4. 窗体设计

    • 如果需要可视化设计,可以在Visual Studio中使用窗体设计器
    • 控件的名称需要与代码中的名称对应
  5. 运行程序

    • 默认用户名:admin
    • 默认密码:需要根据数据库中的实际密码填写

这个完整的UI层实现了所有功能:

  • 登录认证
  • 员工数据分页显示
  • 员工信息详情展示
  • 搜索功能(员工姓名、部门、负责人)
  • 新增/编辑/删除员工
  • 新增/编辑/删除部门
  • 数据导出到Excel
  • 记住密码功能
  • 右键菜单操作
相关推荐
寻星探路2 小时前
【全景指南】JavaEE 深度解析:从 Jakarta EE 演进、B/S 架构到 SSM 框架群实战
java·开发语言·人工智能·spring boot·ai·架构·java-ee
七夜zippoe2 小时前
微服务架构演进实战 从单体到微服务的拆分原则与DDD入门
java·spring cloud·微服务·架构·ddd·绞杀者策略
东城绝神11 小时前
《Linux运维总结:基于ARM64+X86_64架构使用docker-compose一键离线部署MySQL8.0.43 NDB Cluster容器版集群》
linux·运维·mysql·架构·高可用·ndb cluster
Coder_Boy_13 小时前
基于SpringAI的在线考试系统-0到1全流程研发:DDD、TDD与CICD协同实践
java·人工智能·spring boot·架构·ddd·tdd
龙之叶16 小时前
【Android Monkey源码解析四】- 异常捕获/页面控制
android·windows·adb·monkey
优选资源分享17 小时前
Advanced Renamer v4.20 便携版 批量文件重命名工具
windows·实用工具
澄澈青空~17 小时前
畜牧业养牛技术与商家微服务解决方案
微服务·云原生·架构
linweidong18 小时前
C++大型系统中如何组织头文件和依赖树?
java·c++·架构
代码游侠18 小时前
嵌入式开发——ARM Cortex-A7内核和i.MX6处理器相关的底层头文件
arm开发·笔记·嵌入式硬件·学习·架构