ОК. Я не уверен на 100%, куда вы идете с этим, но я приведу пример.Не уверен, как это будет работать с MVVM, но я предполагаю, что должно.
В вашей модели добавьте это:
public bool IsValid
{
get
{
return (GetRuleViolations().Count() == 0);
}
}
public override IEnumerable<RuleViolation> GetRuleViolations()
{
if (string.IsNullOrEmpty(Name))
yield return new RuleViolation("Name can't be empty", "Name");
else if (Name.Length >= 30)
yield return new RuleViolation("Name can't be more then 30 letters", "Name");
if (!string.IsNullOrEmpty(Address))
{
if (!Web.Contains("http"))
yield return new RuleViolation("Address must be bla bal", "Address");
}
// and so on
yield break;
}
и создайте класс RuleViolation:
public class RuleViolation
{
public string ErrorMessage { get; private set; }
public string PropertyName { get; private set; }
public RuleViolation(string errorMessage, string propertyName)
{
ErrorMessage = errorMessage;
PropertyName = propertyName;
}
}
Теперь, когда вы вызываете свой метод IsValid, он проверяет каждое свойство.Если вы используете INotifyPropertyChanged, я бы добавил IsValid как свойство для обновления каждый раз, когда вы обновляете любое проверенное свойство.Если у вас есть базовый класс модели, вы можете добавить его туда и определить правила для каждого производного класса:
public bool IsValid
{
get
{
return (GetRuleViolations().Count() == 0);
}
}
public abstract IEnumerable<RuleViolation> GetRuleViolations();
Теперь вопрос заключается в том, как отобразить эту ошибку в вашем пользовательском интерфейсе.Ну, это зависит от того, что пользовательский интерфейс.Давайте предположим, что приложение WPF.Затем вам нужно, чтобы ваша модель наследовала IDataErrorInfo, и вы можете использовать ее следующим образом:
#region IDataErrorInfo Members
public string Error
{
get { return null; }
}
public string this[string name]
{
get
{
string result = null;
if (this.GetRuleViolations().Where(v => v.PropertyName == name).Count() > 0)
{
result = this.GetRuleViolations().Where(v => v.PropertyName == name).First().ErrorMessage;
}
return result;
}
}
Тогда в коде XAML:
<TextBox Style="{StaticResource ValidationTextBox}" >
<TextBox.Text>
<Binding Path="Name" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<DataErrorValidationRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<Style x:Key="ValidationTextBox" TargetType="TextBox" >
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<Border BorderBrush="Red" BorderThickness="1">
<AdornedElementPlaceholder />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
Если вы используете Asp.net в качестве пользовательского интерфейсаЕсть также некоторые встроенные методы для отображения ошибок в формах.
Я мог бы быть способом, и могут быть более эффективные способы, но я надеюсь, что это поможет несколько.