一、前言
前提是 C1FlexGrid 中存在数据绑定列和自定义列(非数据绑定列),此时如果该行编辑后出现排他错误,自定义列也会出现验证结果的红色边框:
但是自定义列如果只是一些按钮操作,提示说明什么的,与前面绑定的数据并无关系,不想参与到前面的排他错误提示,也就是不想要这个红色边框,该如何处理?
二、实现
1 using System.Collections.ObjectModel; 2 using System.ComponentModel; 3 4 namespace Validation 5 { 6 public class DataObject : IDataErrorInfo 7 { 8 public string Name { get; set; } 9 public int Age { get; set; } 10 public string Sex { get; set; } 11 public string UpdateErrorMessage { get; set; } 12 13 // property-level 14 public string this[string propertyName] 15 { 16 get 17 { 18 if (!string.IsNullOrEmpty(UpdateErrorMessage)) 19 { 20 return UpdateErrorMessage; 21 } 22 if (propertyName == "Name" && string.IsNullOrWhiteSpace(Name)) 23 { 24 return "Name is invalid!"; 25 } 26 27 return string.Empty; 28 } 29 } 30 31 // item-level 32 string IDataErrorInfo.Error 33 { 34 get 35 { 36 if (!string.IsNullOrEmpty(UpdateErrorMessage)) 37 { 38 return UpdateErrorMessage; 39 } 40 41 return ""; 42 } 43 } 44 45 46 // 初始化数据源 47 public static ObservableCollection<DataObject> InitDataSource() 48 { 49 ObservableCollection<DataObject> itemSource = new ObservableCollection<DataObject>(); 50 itemSource.Add(new DataObject() { 51 Name = "aa", 52 Age = 11, 53 Sex = "男" }); 54 itemSource.Add(new DataObject() { 55 Name = "vv", 56 Age = 15, 57 Sex = "男" }); 58 itemSource.Add(new DataObject() { 59 Name = "aa", 60 Age = 11, 61 Sex = "男" }); 62 itemSource.Add(new DataObject() { 63 Name = "aa", 64 Age = 11, 65 Sex = "男" }); 66 itemSource.Add(new DataObject() { 67 Name = "aa", 68 Age = 11, 69 Sex = "男" }); 70 itemSource.Add(new DataObject() { 71 Name = "aa", 72 Age = 11, 73 Sex = "男" }); 74 itemSource.Add(new DataObject() { 75 Name = "aa", 76 Age = 11, 77 Sex = "男" }); 78 79 return itemSource; 80 } 81 } 82 }
首先我模拟一个验证方法,当输入的 Name 为 kk 时,即出现排他错误:
// 数据验证 private bool Verify(int rowIndex) { bool flag = false; DataObject selectedItem = (DataObject)flx.SelectedItem; flag = (selectedItem != null && selectedItem.Name.Equals("kk")); return flag; }
然后在行编辑完成时(RowEditEnding),进行判断处理排他错误信息:
private void flx_RowEditEnding(object sender, C1.WPF.FlexGrid.CellEditEventArgs e) { C1FlexGrid flexGrid = sender as C1FlexGrid; // 满足某些条件时出现验证错误 if (Verify(e.Row)) { ((DataObject)flexGrid.SelectedItem).UpdateErrorMessage = "Error!!"; // 重绘当前行 flexGrid.Invalidate(new CellRange(e.Row, -1, e.Row, flexGrid.Columns.Count - 1)); // 重绘该行行头部分,已显示小红点提示 flexGrid.RowHeaders.Invalidate(); e.Cancel = true; } else { ((DataObject)flexGrid.SelectedItem).UpdateErrorMessage = ""; } }
其中
flexGrid.Invalidate(new CellRange(e.Row, -1, e.Row, flexGrid.Columns.Count - 1));
是为了重新绘制当前行,否则当设置完排他错误 UpdateErrorMessage 时,只会绘制当前单元格的红色边框,该行其他的单元格不会绘制;
其中
flexGrid.RowHeaders.Invalidate();
是为了绘制行头的那个红色点;
下面才是解决问题的关键:
其实也很简单,就是将最后自定义列重新绘制一遍即可:
public class MyCellFactory : CellFactory { public override void CreateCellContent(C1FlexGrid grid, Border bdr, CellRange rng) { base.CreateCellContent(grid, bdr, rng); // 处理最后一列非绑定列的边框重绘 if (rng.Column == grid.Columns.Count - 1) { bdr.BorderThickness = new Thickness(0, 0, 1, 1); bdr.BorderBrush = new SolidColorBrush(Color.FromArgb(255, 240, 240, 240)); bdr.UpdateDefaultStyle(); } } }
其中 base.CreateCellContent(grid, bdr, rng); 里面就已经将单元格的排他错误样式绘制完了,所以一定要在这之后再手动绘制自定义列,参考上面的代码;
最后实现的效果如下: