Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
могут быть получены при помощиотраженийНу вот кем надо было быть, чтобы перевести в этом контексте Reflection как отражение? Кого вообще нанимали для перевода MSDN? Они хоть иногда читали книжки кроме букваря? Должно быть, нет, ибо иначе они бы знали, что есть такое слово, как рефлексия, которое хоть и является заимствованием с латыни, но уже давно и прочно укоренилось в русском языке, а смысл передаёт наиболее точно. Хочется взять и расстрелять просто.
public virtual string this[string columnName]
{
get { return AttributesValidation.Validate(this, columnName); }
}
internal static class AttributesValidation
{
public static string Validate(IDataErrorInfo source, string columnName)
{
var type = source.GetType();
var property = type.GetProperty(columnName);
var validators = (ValidationAttribute[]) property.GetCustomAttributes(typeof (ValidationAttribute), true);
if (validators.Any())
{
var value = property.GetValue(source, null);
var errors = validators.Where(v => !v.IsValid(value)).Select(v => v.ErrorMessage ?? "").ToArray();
return string.Join(Environment.NewLine, errors);
}
return string.Empty;
}
}
[TextBox Text="{Binding Path=Name, Mode=TwoWay, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" /]
class MyForm{
int _errCount;
public MyForm()
{
Validation.AddErrorHandler(this, OnChildControlError); // и на каждое появление ошибки валидации или пропадание ошибки валидации будет вызываться OnChildControlError.
}
protected void OnChildControlError(object sender, ValidationErrorEventArgs e)
{
switch (e.Action)
{
case ValidationErrorEventAction.Added:
_errCount += 1;
break;
case ValidationErrorEventAction.Removed:
_errCount -= 1;
break;
default:
throw new ArgumentOutOfRangeException();
}
// теперь в переменной _errCount у нас записано количество ошибочных полей, и мы можем делать какое-то действие, например задизаблить кнопку OK. Я предпочитаю объявить DependencyProperty Valid, и с ним работать в xaml.
Valid = _errCount == 0;
}
Таким образом, если всё это сплести в одну кучу, то мы получаем:
1. ViewModel умеет сообщать о своих ошибках через [propertyName]
2. Специальный валидатор умеет валидировать модели через атрибуты
3. xaml умеет помечать красным невалидные филды
4. Viewшка (например, форма или UserControl) умеет считать невалидные филды внутри себя и имеет DependcyProperty Valid, к которому можно биндить Enabled-свойство кнопок.
Вывод сообщений об ошибке в xaml я не буду расписывать, так как это есть в msdn и stackoverflow, а комментарий итак получается очень большим.public virtual string this[string columnName]
{
get { return AttributesValidation.Validate(this, columnName); }
}
internal static class AttributesValidation
{
public static string Validate(IDataErrorInfo source, string columnName)
{
var type = source.GetType();
var property = type.GetProperty(columnName);
var validators = (ValidationAttribute[]) property.GetCustomAttributes(typeof (ValidationAttribute), true);
if (validators.Any())
{
var value = property.GetValue(source, null);
var errors = validators.Where(v => !v.IsValid(value)).Select(v => v.ErrorMessage ?? "").ToArray();
return string.Join(Environment.NewLine, errors);
}
return string.Empty;
}
}
[TextBox Text="{Binding Path=Name, Mode=TwoWay, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" /]
class MyForm{
int _errCount;
public MyForm()
{
Validation.AddErrorHandler(this, OnChildControlError); // и на каждое появление ошибки валидации или пропадание ошибки валидации будет вызываться OnChildControlError.
}
protected void OnChildControlError(object sender, ValidationErrorEventArgs e)
{
switch (e.Action)
{
case ValidationErrorEventAction.Added:
_errCount += 1;
break;
case ValidationErrorEventAction.Removed:
_errCount -= 1;
break;
default:
throw new ArgumentOutOfRangeException();
}
// теперь в переменной _errCount у нас записано количество ошибочных полей, и мы можем делать какое-то действие, например задизаблить кнопку OK. Я предпочитаю объявить DependencyProperty Valid, и с ним работать в xaml.
Valid = _errCount == 0;
}
Применение атрибутов в C#