I created my own custom authentication system for WPF using attribute-based authentication. I am stuck in the last step to highlight a TextBox. In fact, it selects text fields, but all text fields depend on a single HasError property.
public class RegistrationViewModel : ViewModel
{
[NotNullOrEmpty("FirstName should not be null or empty")]
public string FirstName { get; set; }
[NotNullOrEmpty("Middle Name is required!")]
public string MiddleName { get; set; }
[NotNullOrEmpty("LastName should not be null or empty")]
public string LastName { get; set; }
public bool HasError
{
get
{
**return Errors.Count > 0;
}
}
}
And here is the XAML code:
<Style x:Key="textBoxStyle" TargetType="{x:Type TextBox}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=HasError}" Value="True">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
The problem with the above code is that it will highlight all text fields that use "textBoxStyle", even if they are valid. This is because HasError does not check based on an individual property, but as a whole.
Any ideas?
UPDATE 1:
ViewModel contains a collection of errors:
public class ViewModel : ContentControl, INotifyPropertyChanged
{
public static DependencyProperty ErrorsProperty;
static ViewModel()
{
ErrorsProperty = DependencyProperty.Register("Errors", typeof(ObservableCollection<BrokenRule>), typeof(ViewModel));
}
public ObservableCollection<BrokenRule> Errors
{
get { return (ObservableCollection<BrokenRule>)GetValue(ErrorsProperty); }
set
{
SetValue(ErrorsProperty,value);
OnPropertyChanged("HasError");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
}
UPDATE 2:
My check mechanism:
public bool Validate(object viewModel)
{
_brokenRules = new List<BrokenRule>();
var properties = viewModel.GetType().GetProperties();
foreach(var property in properties)
{
var attribues = property.GetCustomAttributes(typeof (EStudyValidationAttribute), false);
foreach(EStudyValidationAttribute att in attribues)
{
bool isValid = att.IsValid(property.GetValue(viewModel,null));
if(isValid) continue;
var brokenRule = new BrokenRule()
{
PropertyName = property.Name,
Message = att.Message
};
_brokenRules.Add(brokenRule);
}
}
var list = _brokenRules.ToObservableCollection();
viewModel.GetType().GetProperty("Errors").SetValue(viewModel,list,null);
return (_brokenRules.Count() == 0);
}