A another way to implement it is setting binding in TextBox loaded eventhandler.
Below is the xaml of TextBox:
<TextBox Grid.Row="0"
x:Name="txtName"
Text="{Binding Name}"
Loaded="TxtName_OnLoaded" />
Now in code behind for TxtName_OnLoaded eventhandler will will create new Binding object and will initialize it as per our needs. Also we will add ValidationRule into it.
private void TxtName_OnLoaded(object sender, RoutedEventArgs e)
{
ApplicationViewModel appVm = this.DataContext as ApplicationViewModel;
TextBox TxtName = sender as TextBox;
if (TxtName == null)
return;
Binding newBinding = new Binding("Name");
newBinding.ValidatesOnDataErrors = true;
newBinding.ValidatesOnExceptions = true;
newBinding.NotifyOnValidationError = true;
newBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
validator.ErrorMessage = "Labware name should be unique.";
validator.ApplicationViewModel = appVm;
if (!newBinding.ValidationRules.Contains(validator))
newBinding.ValidationRules.Add(validator);
TxtName.SetBinding(TextBox.TextProperty, newBinding);
}
As you can see in above implementation we have created an object of Binding with new binding path. Also assigned UpdateSourceTrigger to newly created Binding object.
A binding can have multiple validation rules. We will add a validation rule into it. Now we can set the binding to the TextProperty of textbox.
Benefits: You can bind multiple dependency objects to the properties of Validation Rule object from code behind which is not possible with xaml. For example:
I used it to validate inputs on TextChanged event, where I compare input with the list of Items stored as public ObservableCollection property, bound with Grid, in ApplicationViewModel. Code of ValidationRule is as follows:
public class UniqueValueValidator : ValidationRule
{
public string ErrorMessage { get; set; }
public ApplicationViewModel ApplicationViewModel { get; set; }
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
if (value == null)
return null;
var lws = ApplicationViewModel.Inputs.Where(s => s.Name.Equals(value.ToString())).FirstOrDefault();
if (lws != null)
return new ValidationResult(false, ErrorMessage);
return new ValidationResult(true, null);
}
}
Above code takes input and checks availability in the "Inputs" observable collection. Rule give false ValidationResult if value exists. Through this implementation I check uniqueness of inputs on run-time.
Hope you guys have enjoyed it.