Checking the syntax of related controls in WPF

I have a WPF dialog with several text fields on it. Text fields are bound to my business object and have WPF validation rules.

The problem is that the user can perfectly click the "OK" button and close the dialog box without actually entering data in the text fields. Validation rules never work, because the user did not even try to enter information in the text fields.

Is it possible to enforce verification checks and determine if some verification rules are violated?

I could do this when the user tries to close the dialog and prevent him from doing this if any validation rules are violated.

Thank.

+49
validation wpf business-objects
Jan 27 '09 at 13:40
source share
5 answers

We have this problem in our application. Validation is only performed when bindings are updated, so you need to update them manually. We do this in the Loaded event window:

public void Window_Loaded(object sender, RoutedEventArgs e) { // we manually fire the bindings so we get the validation initially txtName.GetBindingExpression(TextBox.TextProperty).UpdateSource(); txtCode.GetBindingExpression(TextBox.TextProperty).UpdateSource(); } 

An error pattern will appear (red outline) and set the Validation.HasError property, which we call the OK button to disable:

 <Button x:Name="btnOK" Content="OK" IsDefault="True" Click="btnOK_Click"> <Button.Style> <Style TargetType="{x:Type Button}"> <Setter Property="IsEnabled" Value="false" /> <Style.Triggers> <!-- Require the controls to be valid in order to press OK --> <MultiDataTrigger> <MultiDataTrigger.Conditions> <Condition Binding="{Binding ElementName=txtName, Path=(Validation.HasError)}" Value="false" /> <Condition Binding="{Binding ElementName=txtCode, Path=(Validation.HasError)}" Value="false" /> </MultiDataTrigger.Conditions> <Setter Property="IsEnabled" Value="true" /> </MultiDataTrigger> </Style.Triggers> </Style> </Button.Style> </Button> 
+56
Jan 30 '09 at 19:28
source share

In 3.5SP1 / 3.0SP2, they also added a new property to the ValidationRule base, namely ValidatesOnTargetUpdated = "True" . This will trigger a check as soon as the source object is bound, and not just when updating the target control. It may not be exactly what you want, but it's nice to see everything you need to fix first.

It works something like this:

 <TextBox.Text> <Binding Path="Amount" StringFormat="C"> <Binding.ValidationRules> <validation:RequiredValidationRule ErrorMessage="The pledge amount is required." ValidatesOnTargetUpdated="True" /> <validation:IsNumericValidationRule ErrorMessage="The pledge amount must be numeric." ValidationStep="ConvertedProposedValue" ValidatesOnTargetUpdated="True" /> </Binding.ValidationRules> </Binding> </TextBox.Text> 
+58
Mar 21 '09 at 6:49
source share

Here is an alternative way that does not require calling "UpdateSource ()" or "UpdateTarget ()":

 var binding = thingToValidate.GetBinding(propertyToValidate); foreach (var rule in binding.ValidationRules) { var value = thingToValidate.GetValue(propertyToValidate); var result = rule.Validate(value, CultureInfo.CurrentCulture); if (result.IsValid) continue; var expr = BindingOperations.GetBindingExpression(thingToValidate, propertyToValidate); if (expr == null) continue; var validationError = new ValidationError(rule, expr); validationError.ErrorContent = result.ErrorContent; Validation.MarkInvalid(expr, validationError); } 
+1
Jun 24 '16 at 23:00
source share

Use the method suggested by Robert McNee. For example:

 //force initial validation foreach (FrameworkElement item in grid1.Children) { if (item is TextBox) { TextBox txt = item as TextBox; txt.GetBindingExpression(TextBox.TextProperty).UpdateSource(); } } 

But, MAKE SURE that Related Controls Are Visibles Before Running This Code!

0
Jul 25 2018-12-12T00:
source share

using INotifyPropertychanged in your data object

 public class MyObject : INotifyPropertyChanged { string _MyPropertyToBind = string.Empty; public string MyPropertyToBind { get { return _MyPropertyToBind; } set { _MyPropertyToBind = value; NotifyPropertyChanged("MyPropertyToBind"); } } public void NotifyPropertyChanged(string property) { if (this.PropertyChanged != null) { this.PropertyChanged(this, new PropertyChangedEventArgs(property)); } } #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; #endregion } 

you can add the following code to your code

 <TextBox Text="{Binding MyPropertyToBind, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" > 

The text field senses the propertychanged event of the datacontext object (MyObjet in our example) and assumes that it is fired when the original data has been updated.

it automatically forcibly updates the control

No need to call yourself UpdateTarget method

-3
Oct 11 2018-10-11
source share



All Articles