Класс данных:
Код: Выделить всё
public class MyAwesomeClass : IDataErrorInfo, INotifyPropertyChanged
{
string _Name;
public string Name { get { return _Name; } set { if(Name is null || !Name.Equals(value)) { _Name = value; Changed(nameof(Name)); } } }
int _MyVal;
[CustomValidation(typeof(MyAwesomeValidator), nameof(MyAwesomeValidator.ValidateIntVal))]
public int MyVal { get { return _MyVal; } set { if(!MyVal.Equals(value)) { _MyVal = value; Changed(nameof(MyVal)); } } }
private void Changed(string property)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}
//Nicked from: https://reza-aghaei.com/dataannotations-validation-attributes-in-windows-forms/
[Browsable(false)]
public string this[string property]
{
get
{
var propertyDescriptor = TypeDescriptor.GetProperties(this)[property];
if (propertyDescriptor == null)
return string.Empty;
var results = new List();
var result = Validator.TryValidateProperty(
propertyDescriptor.GetValue(this),
new ValidationContext(this, null, null)
{ MemberName = property },
results);
if (!result)
return results.First().ErrorMessage;
return string.Empty;
}
}
[Browsable(false)]
public string Error
{
get
{
var results = new List();
var result = Validator.TryValidateObject(this,
new ValidationContext(this, null, null), results, true);
if (!result)
return string.Join(Environment.NewLine, results.Select(x => x.ErrorMessage));
else
return null;
}
}
public static IEnumerable DummyData
{
get { return new [] { new MyAwesomeClass("a", -2),
new MyAwesomeClass("b", 3),
new MyAwesomeClass("c", 8)
};
}
}
}
Код: Выделить всё
public class CustomValidationResult : ValidationResult
{
public enum ResultState { Warning, Error }
public ResultState State { get; private set; }
public CustomValidationResult(string errorMessage, ResultState state) : base(errorMessage)
{
ResultState = state;
}
public static ValidationResult Success
{
get { return ValidationResult.Success; }
}
}
Код: Выделить всё
public class MyAwesomeValidator
{
public static ValidationResult ValidateIntVal(int value, ValidationContext Context)
{
if (value < 0)
return new CustomValidationResult("The value cannot be smaller than 0", CustomValidationResult.ResultState.Error);
if (value < 5)
return new CustomValidationResult("The value is a bit small, isn't it?", CustomValidationResult.ResultState.Warning);
return CustomValidationResult.Success;
}
}
Код: Выделить всё
class DataGridViewCellFormatter
{
DataGridView Dgv;
public DataGridViewCellFormatter(DataGridView dgv)
{
Dgv = dgv;
Dgv.CellFormatting += Dgv_CellFormatting;
}
private void Dgv_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
DataGridViewCell cell = Dgv.Rows[e.RowIndex].Cells[e.ColumnIndex];
if (!string.IsNullOrWhiteSpace(cell.ErrorText))
{
cell.Style.BackColor = Color.Red;
}
else
{
cell.Style.BackColor = cell.OwningColumn.DefaultCellStyle.BackColor;
}
}
}
Код: Выделить всё
public partial class frm_DemoForm : Form
{
BindingList Data;
DataGridViewCellFormatter coloring;
public frm_DemoForm()
{
Data = new BindingList(MyAwesomeClass.DummyData.ToList());
InitializeComponent();
coloring = new DataGridViewCellFormatter(dataGridView1);
dataGridView1.DataSource = Data;
}
}
НО
Эта форма проверки допускает только двоичное форматирование: ошибка или отсутствие ошибки. Если я хочу окрасить ячейку в оранжевый цвет, если это всего лишь предупреждение, мне нужно добавить к тексту ошибки префикс или суффикс «
Код: Выделить всё
[Warning]" и "[Error]НО
Поскольку у меня уже есть такой хороший CustomValidationResult, который обеспечивает нужную мне степень детализации через свойство State, мне было интересно, есть ли способ элегантно подключить DataGridView к фактическому Объект(ы) ValidationResult и воздействуйте на них, а не на ErrorText каждой ячейки, которую я не хочу рассылать спамом с помощью "
Код: Выделить всё
[Warning]