编辑
2025-11-01
C#
00

在开发Windows Forms应用程序时,DataGridView是我们常用的数据展示控件。但当需要加载大量数据(如十万、百万级记录)时,你可能会遇到性能瓶颈:界面卡顿、内存占用过高、加载时间过长。本文将系统讲解DataGridView大数据量下的性能优化策略,帮助你构建高效稳定的数据展示界面。

性能挑战分析

处理大数据量时,DataGridView主要面临以下挑战:

  • 内存占用过高:加载全部数据会占用大量内存
  • UI线程阻塞:数据加载时UI冻结,用户体验差
  • 渲染性能问题:大量行的渲染导致滚动卡顿

三种数据加载策略

根据不同应用场景,我们可以采用以下三种策略:

C#
// 数据加载策略 public enum LoadStrategy { Lazy, // 延迟加载:按需获取数据 Batch, // 分批加载:分段获取固定数量数据 Virtual // 虚拟模式:只加载可视区域数据 }

1. 延迟加载(Lazy Loading)

适合数据量中等的场景,用户触发特定动作时才加载数据。

2. 分批加载(Batch Loading)

适合需要全量数据但总量较大的情况,分多次加载固定数量的数据。

3. 虚拟模式(Virtual Mode)

适合海量数据展示,只加载可视区域数据,是本文重点讲解的优化方案。

虚拟模式实现详解

数据源接口设计

首先,我们定义一个通用的数据源接口:

C#
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AppEditDataGrid { // 数据源接口 public interface IDataSource<T> { // 获取指定范围的数据 List<T> GetData(int startIndex, int count); // 获取总记录数 int GetTotalCount(); } }

这个接口设计的关键在于:

  • 支持分段获取数据而非一次加载全部
  • 通过GetTotalCount()获取总记录数,告知GridView总行数
编辑
2025-11-01
C#
00

在.NET开发领域,处理Word文档一直是常见需求。无论是生成报表、合同模板、证书还是各类公文,开发者都需要一种高效、简便的方式来实现Word文档的动态生成。传统解决方案往往依赖于Microsoft Office COM组件,不仅需要安装Office,还面临着跨平台兼容性差、性能低下等问题。

现在,一款强大的开源库——MiniWord横空出世,为.NET开发者提供了全新选择。本文将全面介绍这款由.NET开发者社区备受推崇的Word模板处理库,帮助你快速掌握其强大功能。

MiniWord:什么是它?为什么选择它?

MiniWord是一个.NET平台下的Word模板引擎,它采用类似Vue、React的模板方式,通过在Word文档中定义变量占位符,再结合数据源,快速生成目标Word文档。作为继MiniExcel之后的又一开源作品,MiniWord专注于解决Word文档的模板处理问题。

主要特点

  1. 跨平台支持:完全兼容Windows、Linux和macOS
  2. 零依赖:不依赖Microsoft Office COM+组件
  3. 高性能:采用底层OpenXML技术,处理速度快
  4. 简单易用:使用类似Vue、React的模板语法,学习成本低
  5. 功能丰富:支持文本替换、表格处理、图片插入等多种功能
  6. 开源免费:遵循MIT开源协议,可自由使用和修改

安装与环境准备

MiniWord通过NuGet包管理器提供,安装非常简单:

C#
// 通过NuGet包管理器安装 Install-Package MiniWord // 或者使用.NET CLI dotnet add package MiniWord

image.png

编辑
2025-10-31
C#
00

在Windows窗体应用程序开发中,数据绑定是一项核心技术,能够有效地将用户界面与底层数据源连接起来。本文将详细介绍如何在C# Windows Forms应用中实现复杂数据绑定,特别是使用DataGridView控件展示和管理数据。无论你是C#初学者还是希望提升数据处理能力的开发者,本教程都能帮助你掌握这一重要技能。

什么是数据绑定?

数据绑定是指将UI控件与数据源建立连接,使得数据能够自动在两者之间流动。在Windows Forms中,这意味着当数据源发生变化时,UI控件会自动更新;同样,当用户通过UI修改数据时,这些更改也会反映到底层数据源中。

BindingSource类的作用

BindingSource是实现复杂数据绑定的关键组件,它充当UI控件与数据源之间的中介,提供以下优势:

  • 简化数据源与控件之间的连接
  • 支持数据筛选和排序
  • 提供内置的导航功能
  • 处理数据变更通知
  • 简化多控件共享同一数据源的实现

实战案例:员工管理系统

下面,我们将通过一个员工管理系统的案例,展示如何实现复杂数据绑定。

第一步:定义数据模型

首先,我们需要创建一个代表员工的数据模型类:

C#
// 员工数据模型 public class Employee { public int Id { get; set; } // 员工ID public string Name { get; set; } // 姓名 public string Department { get; set; } // 所属部门 public decimal Salary { get; set; } // 薪资 public DateTime HireDate { get; set; } // 入职日期 public bool IsActive { get; set; } // 在职状态 }

第二步:初始化数据源

接下来,我们需要创建一个数据源,在实际应用中这通常来自数据库,但在本例中我们使用模拟数据:

C#
// 初始化员工数据 private void InitializeDataSource() { // 模拟数据库数据 employeeList = new List<Employee> { new Employee { Id = 1, Name = "张三", Department = "技术部", Salary = 8000, HireDate = DateTime.Now.AddYears(-3), IsActive = true }, new Employee { Id = 2, Name = "李四", Department = "市场部", Salary = 7000, HireDate = DateTime.Now.AddYears(-2), IsActive = true }, new Employee { Id = 3, Name = "王五", Department = "人事部", Salary = 6000, HireDate = DateTime.Now.AddYears(-1), IsActive = false } }; }

第三步:配置DataGridView并绑定数据

最后,我们将数据源与DataGridView控件绑定,并自定义显示效果:

C#
// 配置DataGridView并绑定数据 private void SetupDataGridView() { // 创建绑定源作为UI与数据之间的桥梁 bindingSource = new BindingSource(); bindingSource.DataSource = employeeList; // 将绑定源关联到DataGridView dataGridView1.DataSource = bindingSource; // 自定义列显示 dataGridView1.Columns["Id"].Visible = false; // 隐藏ID列 dataGridView1.Columns["Name"].HeaderText = "姓名"; dataGridView1.Columns["Department"].HeaderText = "部门"; dataGridView1.Columns["Salary"].HeaderText = "薪资"; dataGridView1.Columns["HireDate"].HeaderText = "入职日期"; dataGridView1.Columns["IsActive"].HeaderText = "在职状态"; }
编辑
2025-10-31
C#
00

DataGridView作为Windows窗体应用程序中最常用的数据展示控件,其灵活的单元格渲染机制为开发者提供了无限可能。本文将深入剖析DataGridView单元格渲染的核心技术,帮助开发者解锁自定义单元格渲染的艺术。

单元格渲染基础详解

基础渲染类继承

C#
using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace AppDataGrid { public class CustomTextCell : DataGridViewTextBoxCell { protected override void Paint( Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) { // 修改:我们需要绘制除了文本之外的所有部分(背景、边框等) // 通过排除文本部分,避免基类绘制文本造成重叠 DataGridViewPaintParts partsWithoutText = paintParts & ~DataGridViewPaintParts.ContentForeground; // 调用基类渲染方法,但不包括文本部分 base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, partsWithoutText); // 只有当需要绘制内容前景(文本)时才进行自定义文本绘制 if ((paintParts & DataGridViewPaintParts.ContentForeground) != 0 && value != null) { // 抗锯齿绘制 graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; // 自定义文本样式 using (SolidBrush brush = new SolidBrush(Color.Navy)) using (Font customFont = new Font("微软雅黑", 9, FontStyle.Bold)) { // 创建适合文本对齐的StringFormat StringFormat stringFormat = new StringFormat(); stringFormat.Alignment = StringAlignment.Center; stringFormat.LineAlignment = StringAlignment.Center; // 调整文本绘制区域,留出边距 Rectangle textRect = new Rectangle( cellBounds.X + 2, cellBounds.Y + 2, cellBounds.Width - 4, cellBounds.Height - 4); graphics.DrawString( value.ToString(), customFont, brush, textRect, stringFormat ); } } } // 重写Clone方法以确保正确复制单元格 public override object Clone() { return new CustomTextCell(); } // 确保默认新行单元格值正确 public override object DefaultNewRowValue => string.Empty; // ====== 修复编辑功能 ====== // 使用标准的TextBox作为编辑控件 public override Type EditType => typeof(DataGridViewTextBoxEditingControl); // 设置值类型 public override Type ValueType => typeof(string); // 正确处理准备编辑状态 public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle) { // 调用基类方法确保正确初始化编辑控件 base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle); // 获取并配置编辑控件 if (DataGridView.EditingControl is DataGridViewTextBoxEditingControl textBox) { // 如果单元格值不为空,则设置文本框内容 textBox.Text = (Value == null) ? string.Empty : Value.ToString(); // 可选:配置文本框的其他属性,比如字体等 textBox.Font = new Font("微软雅黑", 9, FontStyle.Regular); } } // 确保可以编辑 public override bool ReadOnly { get { return base.ReadOnly; } set { base.ReadOnly = value; } } } // 创建自定义列类型以使用自定义单元格 public class CustomTextColumn : DataGridViewColumn { public CustomTextColumn() : base(new CustomTextCell()) { // 设置列的默认属性 SortMode = DataGridViewColumnSortMode.Automatic; DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; } public override DataGridViewCell CellTemplate { get { return base.CellTemplate; } set { // 确保始终使用自定义单元格类型 if (value != null && !value.GetType().IsAssignableFrom(typeof(CustomTextCell))) { throw new InvalidCastException("必须使用CustomTextCell类型的单元格"); } base.CellTemplate = value; } } } }

image.png

编辑
2025-10-31
C#
00

在现代软件开发中,数据库的迁移是一项常见的任务,尤其是在项目需要从MySQL迁移到SQL Server时。本文将详细介绍一个使用C#编写的数据库迁移工具,它的主要功能是将MySQL数据库中的表结构和数据迁移到SQL Server中。该工具支持获取MySQL表的详细架构信息、创建SQL Server表及其主键和注释支持,并批量迁移数据。

代码实现

Nuget 安装MySql.Data

image.png