ReoGrid 是 C# 编写的.NET 电子表格控件(类似 Excel)。支持单元格合并,边框样式,图案背景颜色,数据格式,冻结,公式,宏和脚本执行,表格事件等。支持 Winform\WPF。
ReoGrid.Mvvm 是针对 ReoGrid.WPF 编写的一个开源类库,用于方便地将控件绑定到模型,从而实现模型(Model)和视图(View)的分离,适用于MVVM模式的开发。
项目地址:https://github.com/IUpdatable/ReoGrid.Mvvm,欢迎star
下面以一个图书信息的简单项目演示如何使用 ReoGrid.Mvvm
. 完整代码见项目 ReoGrid.Mvvm.Demo.
演示效果如图
1. 创建一个 WPF 项目
2. NuGet 安装 ReoGrid.Mvvm
Install-Package ReoGrid.Mvvm
3. 创建一个图书的模型(Model)
1 [WorksheetAttribute(Title = "Books")]2 public class Book: IRecordModel3 {4 [ColumnHeader(Index = 10, IsVisible = false)]5 public int Id { get; set; }6 7 [ColumnHeader(Index = 20, Text = "Name", Width = 150)]8 public string Title { get; set; }9 10 [ColumnHeader(Index = 30)] 11 public string Author { get; set; } 12 13 [ColumnHeader(Index = 35, Text = "Type")] 14 public BindingType BindingType { get; set; } 15 16 [ColumnHeader(Index = 36, Text = "OnSale")] 17 public bool IsOnSale { get; set; } 18 19 [NumberFormat(DecimalPlaces = 2)] 20 [ColumnHeader(Index = 40)] 21 public decimal Price { get; set; } 22 23 [DateTimeFormat( CultureName = "en-US")] 24 [ColumnHeader(Index = 45, Text = "Publish Date", Width = 200)] 25 public DateTime Pubdate { get; set; } 26 27 public int RowIndex { get; set; } 28 }
(1) Model 必须实现IRecordModel
接口
IRecordModel
只有一个 RowIndex
属性, 你完全不用管这个属性,这是 ReoGrid.Mvvm
内部用到的。
(2) WorksheetAttribute
用来说明工作表的名字
可选,不指定该特性,那么就用Model类的类名作为工作表名称。
(3) ColumnHeader
特性中, 必须指定 Index
属性,其他的是可选的。
(4) DateTimeFormat
DateTimeFormat
目前不建议使用
ReoGrid
本身并没有完整实现这些特性。当然,也有可能我理解有误。
4. 在ViewModel中修改:
4.1 创建两个成员变量
1 private ObservableCollection<IRecordModel> _Books; 2 private WorksheetModel _WorksheetModel;
4.2 初始化
1 _Books = new ObservableCollection<IRecordModel>();2 for (int i = 0; i < 10; i++)3 {4 Book book = new Book();5 book.Id = i;6 book.Title = string.Format("Title {0}", i);7 book.Author = string.Format("Author {0}", i);8 book.BindingType = BindingType.Hardback;9 book.IsOnSale = true; 10 book.Price = (decimal)(i * 10.1); 11 book.Pubdate = DateTime.Now; 12 _Books.Add(book); 13 } 14 // 变量 reoGridControl 是 ReoGridControl 的控件元素实例 15 _WorksheetModel = new WorksheetModel(reoGridControl, typeof(Book), _Books); 16 //如果需要在输入值前检查变量的有效性,那么就实现该函数 17 _WorksheetModel.OnBeforeChangeRecord += OnBeforeChangeRecord;
4.3 在 OnBeforeChangeRecord
函数中演示输入值有效性检查
1 private bool? OnBeforeChangeRecord(IRecordModel record, PropertyInfo propertyInfo, object newProperyValue)2 {3 if (propertyInfo.Name.Equals("Price"))4 {5 decimal price = Convert.ToDecimal(newProperyValue);6 if (price > 100m) //假设最大价格是1007 {8 MessageBox.Show("最大价格是 100, 请重新输入!.", "Alert", 9 MessageBoxButton.OK, MessageBoxImage.Warning); 10 return true; // 返回 true 则取消本次输入 11 } 12 } 13 14 return null; 15 }
4.4 增加、删除、移动、编辑 模型(Model)
1 // 增加一条书目信息2 int count = _Books.Count;3 Book book = new Book();4 book.Id = count;5 book.Title = string.Format("Title {0}", count);6 book.Author = string.Format("Author {0}", count);7 book.BindingType = BindingType.Hardback;8 book.IsOnSale = true;9 book.Price = (decimal)(count * 10.11) > 100m ? 100m :(decimal)(count * 10.11); 10 book.Pubdate = DateTime.Now; 11 _Books.Add(book); 12 13 // 移除一条书目信息 14 if (_Books.Count > 0) 15 { 16 _Books.RemoveAt(_Books.Count - 1); 17 } 18 19 // 移动一条书目信息 20 if (_Books.Count > 2) 21 { 22 _Books.Move(0, _Books.Count - 1); 23 } 24 25 // 编辑一条书目信息 26 (_Books[0] as Book).Price = new Random(DateTime.Now.Millisecond).Next(1,100); 27 // 编辑完 模型(Model) 之后要调用 UpadteRecord 函数将模型(Model)的变化同步到视图(View)中 28 _WorksheetModel.UpadteRecord(_Books[0]);