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