C# WinForms 桌面应用

    最后更新: 2025年11月26日

    技术栈概述

    C# WinForms 是微软.NET平台的桌面应用开发技术,使用C#语言和Windows Forms框架构建原生Windows应用程序,具有开发效率高、界面美观的特点。

    技术组成

    组件说明
    C#编程语言
    .NET Framework4.7.2+ 或 .NET 6+
    Windows FormsGUI框架
    ADO.NET数据库访问
    Visual Studio开发IDE

    核心特性

    • 原生Windows:最佳的Windows体验
    • 可视化设计:拖拽式界面设计
    • 丰富控件:DataGridView、TreeView等
    • 开发效率高:快速构建企业应用

    C# WinForms 框架变体说明

    系统提供两个 C# WinForms 变体,满足不同需求:

    C_SHARP (基础版) - 适合简单工具

    特性说明
    平台代码C_SHARP
    技术栈.NET Framework + WinForms
    生成内容基础 Forms、数据访问层、实体类
    适用场景简单工具、小型应用、快速开发
    模板目录project-csharp

    C_SHARP2 (增强版) - 完整 CRUD 系统

    特性说明
    平台代码C_SHARP2
    技术栈.NET Framework + WinForms
    生成内容为每个实体生成 4 种 Forms
    适用场景完整 CRUD 管理系统、企业应用
    模板目录project-csharp2

    C_SHARP2 为每个实体额外生成的 Forms

    Form文件名说明
    数据列表 FormFormData.cs显示所有数据(DataGridView)
    新增数据 FormFormAdd.cs新增数据表单
    编辑数据 FormFormEdit.cs编辑数据表单
    查看详情 FormFormDetail.cs查看数据详情(只读)

    变体选择建议

    您的需求推荐变体
    简单工具、小型应用C_SHARP (基础版)
    完整 CRUD 管理系统C_SHARP2 (增强版)

    💡 提示:两个变体的后端代码(DAL、BLL、Models)完全相同,区别仅在 UI Forms 数量。C_SHARP2 为每个实体自动生成完整的增删改查界面。


    适用场景

    场景说明
    Windows桌面软件企业内部管理系统
    数据管理工具数据库客户端、报表工具
    课程设计C#或.NET课程作业
    小型ERP进销存、财务管理

    项目结构

    ProjectName/ ├── ProjectName.sln # 解决方案文件 ├── ProjectName/ │ ├── Program.cs # 程序入口 │ ├── App.config # 配置文件 │ ├── Models/ # 实体类 │ │ └── Student.cs │ ├── DAL/ # 数据访问层 │ │ ├── DBHelper.cs │ │ └── StudentDAL.cs │ ├── BLL/ # 业务逻辑层 │ │ └── StudentBLL.cs │ └── Forms/ # 窗体 │ ├── MainForm.cs │ ├── MainForm.Designer.cs │ ├── StudentListForm.cs │ └── StudentEditForm.cs └── sql/ └── schema.sql

    核心代码示例

    程序入口 (Program.cs)

    using System; using System.Windows.Forms; namespace ProjectName { static class Program { [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); } } }

    实体类 (Student.cs)

    using System; namespace ProjectName.Models { public class Student { public long Id { get; set; } public string Name { get; set; } public string StudentNo { get; set; } public int Gender { get; set; } public long? ClassId { get; set; } public DateTime CreateTime { get; set; } public DateTime UpdateTime { get; set; } // 显示用属性 public string GenderText => Gender == 1 ? "男" : "女"; } }

    数据库帮助类 (DBHelper.cs)

    using System; using System.Configuration; using System.Data; using System.Data.SqlClient; namespace ProjectName.DAL { public static class DBHelper { private static readonly string ConnStr = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString; public static SqlConnection GetConnection() { return new SqlConnection(ConnStr); } public static DataTable ExecuteDataTable(string sql, params SqlParameter[] parameters) { using (SqlConnection conn = GetConnection()) { using (SqlCommand cmd = new SqlCommand(sql, conn)) { if (parameters != null) cmd.Parameters.AddRange(parameters); SqlDataAdapter adapter = new SqlDataAdapter(cmd); DataTable dt = new DataTable(); adapter.Fill(dt); return dt; } } } public static int ExecuteNonQuery(string sql, params SqlParameter[] parameters) { using (SqlConnection conn = GetConnection()) { conn.Open(); using (SqlCommand cmd = new SqlCommand(sql, conn)) { if (parameters != null) cmd.Parameters.AddRange(parameters); return cmd.ExecuteNonQuery(); } } } public static object ExecuteScalar(string sql, params SqlParameter[] parameters) { using (SqlConnection conn = GetConnection()) { conn.Open(); using (SqlCommand cmd = new SqlCommand(sql, conn)) { if (parameters != null) cmd.Parameters.AddRange(parameters); return cmd.ExecuteScalar(); } } } } }

    数据访问层 (StudentDAL.cs)

    using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using ProjectName.Models; namespace ProjectName.DAL { public class StudentDAL { public List<Student> GetAll() { string sql = "SELECT * FROM student ORDER BY id DESC"; DataTable dt = DBHelper.ExecuteDataTable(sql); List<Student> list = new List<Student>(); foreach (DataRow row in dt.Rows) { list.Add(MapToEntity(row)); } return list; } public Student GetById(long id) { string sql = "SELECT * FROM student WHERE id = @id"; DataTable dt = DBHelper.ExecuteDataTable(sql, new SqlParameter("@id", id)); if (dt.Rows.Count > 0) return MapToEntity(dt.Rows[0]); return null; } public int Insert(Student entity) { string sql = @"INSERT INTO student(name, student_no, gender, class_id, create_time) VALUES(@name, @studentNo, @gender, @classId, @createTime)"; return DBHelper.ExecuteNonQuery(sql, new SqlParameter("@name", entity.Name), new SqlParameter("@studentNo", entity.StudentNo), new SqlParameter("@gender", entity.Gender), new SqlParameter("@classId", (object)entity.ClassId ?? DBNull.Value), new SqlParameter("@createTime", DateTime.Now)); } public int Update(Student entity) { string sql = @"UPDATE student SET name=@name, student_no=@studentNo, gender=@gender, class_id=@classId, update_time=@updateTime WHERE id=@id"; return DBHelper.ExecuteNonQuery(sql, new SqlParameter("@id", entity.Id), new SqlParameter("@name", entity.Name), new SqlParameter("@studentNo", entity.StudentNo), new SqlParameter("@gender", entity.Gender), new SqlParameter("@classId", (object)entity.ClassId ?? DBNull.Value), new SqlParameter("@updateTime", DateTime.Now)); } public int Delete(long id) { string sql = "DELETE FROM student WHERE id = @id"; return DBHelper.ExecuteNonQuery(sql, new SqlParameter("@id", id)); } private Student MapToEntity(DataRow row) { return new Student { Id = Convert.ToInt64(row["id"]), Name = row["name"].ToString(), StudentNo = row["student_no"].ToString(), Gender = Convert.ToInt32(row["gender"]), ClassId = row["class_id"] == DBNull.Value ? null : (long?)Convert.ToInt64(row["class_id"]), CreateTime = Convert.ToDateTime(row["create_time"]), UpdateTime = row["update_time"] == DBNull.Value ? DateTime.MinValue : Convert.ToDateTime(row["update_time"]) }; } } }

    主窗体 (MainForm.cs)

    using System; using System.Windows.Forms; namespace ProjectName.Forms { public partial class MainForm : Form { public MainForm() { InitializeComponent(); } private void MainForm_Load(object sender, EventArgs e) { // 初始化菜单 ToolStripMenuItem studentMenu = new ToolStripMenuItem("学生管理"); studentMenu.Click += (s, args) => ShowChildForm(new StudentListForm()); menuStrip1.Items.Add(studentMenu); } private void ShowChildForm(Form form) { form.MdiParent = this; form.WindowState = FormWindowState.Maximized; form.Show(); } } }

    列表窗体 (StudentListForm.cs)

    using System; using System.Windows.Forms; using ProjectName.BLL; using ProjectName.Models; namespace ProjectName.Forms { public partial class StudentListForm : Form { private StudentBLL studentBLL = new StudentBLL(); public StudentListForm() { InitializeComponent(); InitDataGridView(); LoadData(); } private void InitDataGridView() { dataGridView1.AutoGenerateColumns = false; dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect; dataGridView1.MultiSelect = false; dataGridView1.AllowUserToAddRows = false; dataGridView1.ReadOnly = true; dataGridView1.Columns.Add(new DataGridViewTextBoxColumn { DataPropertyName = "Id", HeaderText = "ID", Width = 60 }); dataGridView1.Columns.Add(new DataGridViewTextBoxColumn { DataPropertyName = "Name", HeaderText = "姓名", Width = 100 }); dataGridView1.Columns.Add(new DataGridViewTextBoxColumn { DataPropertyName = "StudentNo", HeaderText = "学号", Width = 120 }); dataGridView1.Columns.Add(new DataGridViewTextBoxColumn { DataPropertyName = "GenderText", HeaderText = "性别", Width = 60 }); dataGridView1.Columns.Add(new DataGridViewTextBoxColumn { DataPropertyName = "CreateTime", HeaderText = "创建时间", Width = 150 }); } private void LoadData() { dataGridView1.DataSource = studentBLL.GetAll(); } private void btnAdd_Click(object sender, EventArgs e) { StudentEditForm form = new StudentEditForm(null); if (form.ShowDialog() == DialogResult.OK) { LoadData(); } } private void btnEdit_Click(object sender, EventArgs e) { if (dataGridView1.CurrentRow == null) { MessageBox.Show("请先选择一行", "提示"); return; } Student student = dataGridView1.CurrentRow.DataBoundItem as Student; StudentEditForm form = new StudentEditForm(student); if (form.ShowDialog() == DialogResult.OK) { LoadData(); } } private void btnDelete_Click(object sender, EventArgs e) { if (dataGridView1.CurrentRow == null) { MessageBox.Show("请先选择一行", "提示"); return; } if (MessageBox.Show("确定要删除吗?", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { Student student = dataGridView1.CurrentRow.DataBoundItem as Student; studentBLL.Delete(student.Id); LoadData(); } } private void btnRefresh_Click(object sender, EventArgs e) { LoadData(); } } }

    配置文件 (App.config)

    <?xml version="1.0" encoding="utf-8" ?> <configuration> <connectionStrings> <add name="DefaultConnection" connectionString="Server=localhost;Database=your_database;User Id=sa;Password=your_password;" providerName="System.Data.SqlClient" /> </connectionStrings> </configuration>

    运行说明

    开发环境

    1. 使用Visual Studio打开.sln文件
    2. 修改App.config中的数据库连接字符串
    3. 按F5运行

    发布部署

    1. 右键项目 → 发布
    2. 选择文件夹发布
    3. 将发布文件夹复制到目标机器
    4. 确保目标机器安装了.NET Framework

    数据库支持

    支持的数据库类型

    数据库版本NuGet 包连接字符串示例
    MySQL5.7+MySql.DataServer=localhost;Database=your_db;Uid=root;Pwd=password;
    SQLite3.xSystem.Data.SQLiteData Source=database.db;Version=3;
    SQL Server2012+内置Server=localhost;Database=your_db;User Id=sa;Password=pwd;

    ⚠️ 注意:系统当前仅支持以上 3 种数据库。如需其他数据库(如 PostgreSQL、Oracle),需要手动修改配置和驱动。

    配置方法(App.config):

    <connectionStrings> <add name="DefaultConnection" connectionString="Server=localhost;Database=your_database;User Id=sa;Password=your_password;" providerName="System.Data.SqlClient" /> </connectionStrings>

    常见问题

    Q1: C_SHARP 和 C_SHARP2 应该选哪个?

    推荐根据项目复杂度选择

    选择 C_SHARP (基础版)

    • ✅ 简单工具、小型应用
    • ✅ 快速开发原型
    • ✅ 课程作业(不需要完整 CRUD 界面)

    选择 C_SHARP2 (增强版)

    • ✅ 完整的管理系统(需要增删改查界面)
    • ✅ 企业内部应用
    • ✅ 数据管理工具

    区别总结:C_SHARP2 为每个实体自动生成 4 种 Forms(列表、新增、编辑、详情),节省大量开发时间。

    Q2: 连接SQL Server失败?

    检查:

    1. SQL Server服务是否启动
    2. 是否启用TCP/IP协议
    3. 防火墙是否放行1433端口
    4. App.config 中连接字符串是否正确

    Q3: 使用MySQL数据库?

    步骤

    1. 安装 MySql.Data NuGet 包:
      Install-Package MySql.Data
      
    2. 修改 DBHelper.cs 中的连接字符串:
      private static readonly string ConnStr = "Server=localhost;Database=your_db;Uid=root;Pwd=password;";
    3. 修改 SqlConnection 为 MySqlConnection

    Q4: 使用 SQLite 数据库?

    步骤

    1. 安装 System.Data.SQLite NuGet 包
    2. 修改连接字符串:
      private static readonly string ConnStr = "Data Source=database.db;Version=3;";
    3. 修改 SqlConnection 为 SQLiteConnection

    Q5: DataGridView 中文乱码?

    解决方案

    1. 确保数据库编码为 UTF-8
    2. 在连接字符串中添加:
      ;CharSet=utf8;
      

    Q6: 为什么选择 WinForms?

    WinForms 的优势

    • ✅ 原生 Windows 体验,性能最佳
    • ✅ 可视化设计器,拖拽式开发
    • ✅ 丰富的控件库(DataGridView、TreeView 等)
    • ✅ 开发效率高,适合企业内部应用

    适合场景:企业内部管理系统、数据管理工具、课程设计


    💡 提示:WinForms是Windows平台最成熟的桌面开发技术,适合快速开发企业内部应用。

    本文对您有帮助吗?
    提交反馈