I have a WPF Form, that has a text box and a button. I am validating the text box to have only characters. Validation works fine, But I need to disable the button if there are validation error and enable them if there are no validation errors. Below is my code:
<TextBox Name="tbProductName" Grid.Column="1" HorizontalAlignment="Left" Height="25" Margin="4,9,0,0" Grid.Row="1" TextWrapping="Wrap" VerticalAlignment="Top" Width="213"
Text="{Binding Path = ProductCode, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True,NotifyOnValidationError=True}">
<Validation.ErrorTemplate>
<ControlTemplate>
<StackPanel>
<AdornedElementPlaceholder x:Name="textBox"/>
<TextBlock Text="{Binding [0].ErrorContent}" Foreground="Red"/>
</StackPanel>
</ControlTemplate>
</Validation.ErrorTemplate>
</TextBox>
<Button Name ="btnDownload" Content="Download" Grid.Column="2" HorizontalAlignment="Left" Margin="10,10,0,0" Grid.Row="1" VerticalAlignment="Top" Width="87" Height="24" Click="btnDownload_Click"/>
public class ViewModel: System.ComponentModel.INotifyDataErrorInfo
{
private readonly Dictionary<string, ICollection<string>> _validationErrors = new Dictionary<string, ICollection<string>>();
private readonly Model _productCode = new Model();
public string ProductCode
{
get { return _productCode.ProductCode; }
set
{
_productCode.ProductCode = value;
ValidateModelProperty(value, "ProductCode");
}
}
protected void ValidateModelProperty(object value, string propertyName)
{
if (_validationErrors.ContainsKey(propertyName))
_validationErrors.Remove(propertyName);
PropertyInfo propertyInfo = _productCode.GetType().GetProperty(propertyName);
IList<string> validationErrors =
(from validationAttribute in propertyInfo.GetCustomAttributes(true).OfType<ValidationAttribute>()
where !validationAttribute.IsValid(value)
select validationAttribute.FormatErrorMessage(string.Empty))
.ToList();
_validationErrors.Add(propertyName, validationErrors);
RaiseErrorsChanged(propertyName);
}
/* Raise the ErrorsChanged for all properties explicitly */
protected void ValidateModel()
{
_validationErrors.Clear();
ICollection<ValidationResult> validationResults = new List<ValidationResult>();
ValidationContext validationContext = new ValidationContext(_productCode, null, null);
if (!Validator.TryValidateObject(_productCode, validationContext, validationResults, true))
{
foreach (ValidationResult validationResult in validationResults)
{
string property = validationResult.MemberNames.ElementAt(0);
if (_validationErrors.ContainsKey(property))
{
_validationErrors[property].Add(validationResult.ErrorMessage);
}
else
{
_validationErrors.Add(property, new List<string> { validationResult.ErrorMessage });
}
}
}
/* Raise the ErrorsChanged for all properties explicitly */
RaiseErrorsChanged("ProductCode");
}
#region INotifyDataErrorInfo members
public event EventHandler<System.ComponentModel.DataErrorsChangedEventArgs> ErrorsChanged;
private void RaiseErrorsChanged(string propertyName)
{
if (ErrorsChanged != null)
ErrorsChanged(this, new System.ComponentModel.DataErrorsChangedEventArgs(propertyName));
}
public System.Collections.IEnumerable GetErrors(string propertyName)
{
if (string.IsNullOrEmpty(propertyName)
|| !_validationErrors.ContainsKey(propertyName))
return null;
return _validationErrors[propertyName];
}
public bool HasErrors
{
get { return _validationErrors.Count > 0; }
}
#endregion
}
public class Model
{
[Required(ErrorMessage = "You must enter a product code to download.")]
[RegularExpression(@"^[a-zA-Z]+$", ErrorMessage = "The Product Code must only contain letters (a-z, A-Z).")]
public string ProductCode { get; set; }
}
How can I set the isEnabled property of the button to Validation.HasErrors?