ReoGrid.Mvvm:ReoGrid綁定模型

  • 2019 年 11 月 2 日
  • 筆記

ReoGrid 是 C# 編寫的.NET 電子表格控制項(類似 Excel)。支援單元格合併,邊框樣式,圖案背景顏色,數據格式,凍結,公式,宏和腳本執行,表格事件等。支援 WinformWPF。

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]);