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: irecordmodel
 3 {
 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) //假设最大价格是100
 7         {
 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]);