In this post we are going to see how to bind the Error from model to Control ToolTip, For this we have to create a Model and assign the Data Annotation, Then that model should be derive from a ValidatableModelBase where we handle the errors list for model,
class EmployeeEdit:ValidatableViewModelBase
{
private Guid _id;
private string _firstname;
private string _lastname;
private string _phone;
private string _email;
public Guid Id
{
get { return _id; }
set { Set<Guid>(ref _id, value); }
}
[Required]
public string FirstName
{
get { return _firstname; }
set { Set<string>(ref _firstname, value); }
}
[Required]
public string LastName
{
get { return _lastname; }
set { Set<string>(ref _lastname, value); }
}
[Phone]
public string Phone
{
get { return _phone; }
set { Set<string>(ref _phone, value); }
}
[EmailAddress]
public string Email
{
get { return _email; }
set { Set<string>(ref _email, value); }
}
}
public class ViewModelBase : INotifyPropertyChanged
{
protected virtual void Set<T>(ref T member, T val,
[CallerMemberName] string propertyName = null)
{
if (object.Equals(member, val)) return;
member = val;
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged = delegate { };
}
public class ValidatableViewModelBase : ViewModelBase, INotifyDataErrorInfo
{
private Dictionary<string, List<string>> _errorslist =
new Dictionary<string, List<string>>();
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged = delegate { };
public System.Collections.IEnumerable GetErrors(string prop)
{
if (_errorslist.ContainsKey(prop))
return _errorslist[prop];
else
return null;
}
public bool HasErrors
{
get { return _errorslist.Count > 0; }
}
protected override void Set<T>(ref T member, T val,
[CallerMemberName] string propertyName = null)
{
base.Set<T>(ref member, val, propertyName);
ValidateProperty(propertyName, val);
}
private void ValidateProperty<T>(string propname, T value)
{
var res = new List<ValidationResult>();
ValidationContext ctx = new ValidationContext(this);
ctx.MemberName = propname;
Validator.TryValidateProperty(value, ctx, res);
if (res.Any())
{
_errorslist[propname] = res.Select(c => c.ErrorMessage).ToList();
}
else
{
_errorslist.Remove(propname);
}
ErrorsChanged(this, new DataErrorsChangedEventArgs(propname));
}
}
View:
**************
<UserControl.Resources>
<conv:EdittoVisiblityConvertor x:Key="EditConvertor" />
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding
RelativeSource={x:Static RelativeSource.Self},
Path=(Validation.Errors).CurrentItem.ErrorContent}" />
</Trigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<TextBox x:Name="firstNameTextBox" Grid.Column="1"
HorizontalAlignment="Left" Height="24" Margin="3,4,0,4"
Grid.Row="0"
Text="{Binding FirstName, ValidatesOnNotifyDataErrors=True}"
VerticalAlignment="Center" Width="120" Grid.ColumnSpan="3"/>
ViewModel
***********
class AddEditEmployeeViewModel:ViewModelBase
{
private EmployeeEdit _employee;
public EmployeeEdit Employee
{
get { return _employee; }
set
{
Set<EmployeeEdit>(ref _employee, value);
}
}
public RelayCommand SaveCommand;
SaveCommand = new RelayCommand(OnSave, CanSave);
private async void OnSave()
{
}
private bool CanSave()
{
return !Employee.HasErrors;
}
}
From this post you can learn how to Bind a Error from model to Control ToolTip.
No comments:
Post a Comment