1. 为什么WPF开发者需要ReoGrid.Mvvm?
如果你做过WPF项目,肯定遇到过这样的需求:用户想要一个类似Excel的表格来查看和编辑数据。你可能会想到用DataGrid,但DataGrid的样式调整、单元格合并、公式计算这些功能,做起来特别费劲。我之前有个项目,客户要求表格能像Excel一样自由编辑,还能做简单的数据验证,用原生的DataGrid折腾了两周,最后还是放弃了,体验太差了。
后来我发现了ReoGrid,它就像是一个嵌入到WPF里的Excel。单元格合并、边框样式、公式计算、甚至脚本执行,它都支持。但光有控件还不够,在WPF里我们讲究MVVM模式,也就是数据驱动UI。直接操作ReoGrid控件,又回到了“事件驱动”的老路,ViewModel和View又耦合在一起了,代码很难维护。
这时候,ReoGrid.Mvvm 这个开源库就派上用场了。它就像一座桥,把强大的ReoGrid控件和优雅的MVVM模式连接了起来。你不用再在后台代码里写 reoGridControl.CurrentWorksheet.SetCellData 这样的命令式代码,而是像绑定普通的ItemsControl一样,通过ViewModel里的集合去驱动表格的显示和编辑。数据变了,表格自动更新;用户在表格里改了数据,你的模型对象也自动跟着变。这才是WPF开发的正确姿势。
简单来说,ReoGrid.Mvvm解决的核心痛点就是:如何在WPF中,用MVVM的方式,实现一个功能强大、可交互的Excel式数据表格。它特别适合那些需要快速构建后台管理系统、数据录入界面、报表预览与编辑功能的场景。接下来,我就带你从零开始,手把手实现一个完整的Demo,把里面的门道和踩过的坑都讲清楚。
2. 5分钟快速搭建你的第一个可编辑表格
理论说再多不如动手试一下。我们先来快速搭一个能跑起来的例子,感受一下ReoGrid.Mvvm的便捷。
2.1 创建项目与安装依赖
首先,打开Visual Studio,新建一个WPF应用项目,名字随便起,比如 ReoGridMvvmDemo。项目建好后,我们需要通过NuGet安装两个包。
第一个是核心控件 unvell.ReoGrid.WPF。在NuGet包管理器控制台里,输入:
Install-Package unvell.ReoGrid.WPF
或者直接在NuGet图形化界面里搜索“ReoGrid.WPF”进行安装。这里有个小坑要注意:截至我写这篇文章时,最新的3.0.0版本在滚动条处理上可能有点小问题,可能会在边缘留下空白。根据社区经验,如果你遇到奇怪的UI错位,可以尝试安装更稳定的2.2.0版本。安装命令后面可以指定版本号:
Install-Package unvell.ReoGrid.WPF -Version 2.2.0
第二个就是今天的主角 ReoGrid.Mvvm。同样在控制台输入:
Install-Package ReoGrid.Mvvm
这个库的作者是IUpdatable,项目地址在GitHub上,如果你觉得好用,记得去点个Star支持一下。
2.2 定义你的数据模型(Model)
模型是MVVM的基石。我们用一个“图书信息管理”的例子来演示。在项目中新建一个类,叫 Book.cs。
using ReoGrid.Mvvm;
using ReoGrid.Mvvm.Attributes;
using System;
namespace ReoGridMvvmDemo.Models
{
[WorksheetAttribute(Title = "图书清单")]
public class Book : IRecordModel
{
[ColumnHeader(Index = 10, IsVisible = false)]
public int Id { get; set; }
[ColumnHeader(Index = 20, Text = "书名", Width = 180)]
public string Title { get; set; }
[ColumnHeader(Index = 30, Text = "作者", Width = 120)]
public string Author { get; set; }
[ColumnHeader(Index = 35, Text = "装订类型")]
public BindingType BindingType { get; set; }
[ColumnHeader(Index = 36, Text = "是否在售")]
public bool IsOnSale { get; set; }
[NumberFormat(DecimalPlaces = 2)]
[ColumnHeader(Index = 40, Text = "价格")]
public decimal Price { get; set; }
[ColumnHeader(Index = 45, Text = "出版日期", Width = 150)]
public DateTime Pubdate { get; set; }
// IRecordModel 要求的属性,库内部使用,你不用管它
public int RowIndex { get; set; }
}
public enum BindingType
{
平装,
精装,
线装
}
}
我来解释一下这几个关键点:
IRecordModel接口:这是ReoGrid.Mvvm的“入场券”,你的模型类必须实现它。它只有一个RowIndex属性,这个属性是库内部用来跟踪数据行位置的,你完全不用去设置或读取它,就当它不存在。[WorksheetAttribute]特性:用来给这个表格工作表起个名字。比如我这里叫“图书清单”。如果不加这个特性,默认就会用类名“Book”作为工作表名。[ColumnHeader]特性:这是核心!它定义了表格列的所有元数据。Index:必须指定,而且数字要唯一。它决定了列在表格中的显示顺序。我习惯以10为间隔(10,20,30...),这样以后如果想在中间插入一列,可以很方便地设置Index为15。Text:列标题显示的文字。Width:列宽。IsVisible:是否隐藏该列。像Id这种数据库主键,通常不需要给用户看,设为false就藏起来了。
[NumberFormat]和[DateTimeFormat]:这些是数据格式特性。比


357

被折叠的 条评论
为什么被折叠?



