Validate user input

Source: Internet
Author: User

For most programs, displaying data is only half of the battle. the other big challenge is analyzing, accepting, and rejecting data entered by the user. in an ideal world, where all users always enter logical and accurate data, this wocould be a simple task.
In the real world, however, this is not at all the case.

It is our job, as developers and tables ts, to combat the inevitable erroneous and malicious input entered by our users. The WPF binding infrastructure has support for Input Validation. In the next few sections
Of this article, I'll examine how to make use of the WPF support for validation, as well as how to display validation error messages to the user. Input Validation via validationrules

The binding class has a validationrules 'Property, which can store any number of validationrule-Derived classes. Each of those rules can contain some logic that tests to see if the bound value is valid.

WPF only came with one validationrule subclass, called exceptionvalidationrule. developers cocould add that rule to a binding's validationrules and it wocould catch exceptions thrown during updates made to the data source, allowing the UI to display the exception's
Error message. the usefulness of this approach to input validation is debatable, considering that the bedrock of good user experience is to avoid unnecessarily revealing technical details to the user. the error messages in data parsing exceptions are generally
Too technical for most users, but I digress.

Suppose that you have a class that represents an era of time, such as the simple ERA class seen here:
public class Era : INotifyPropertyChanged    {                // Declare the event        public event PropertyChangedEventHandler PropertyChanged;        public Era()        {        }        private DateTime m_StartDate;        public DateTime StartDate        {            get { return m_StartDate; }            set            {                m_StartDate = value;                // Call OnPropertyChanged whenever the property is updated                OnPropertyChanged("StartDate");            }        }        private TimeSpan m_Duration;        public TimeSpan Duration         {            get { return m_Duration; }            set            {                m_Duration = value;                // Call OnPropertyChanged whenever the property is updated                OnPropertyChanged("Duration");            }        }        // Create the OnPropertyChanged method to raise the event        protected void OnPropertyChanged(string prop)        {            PropertyChangedEventHandler handler = PropertyChanged;            if (handler != null)            {                handler(this, new PropertyChangedEventArgs(prop));            }        }    }

If you want to allow the user to edit the start date and duration of an era, you can use two textbox controls and bind their text properties to the properties of an ERA instance. since the user cocould enter any text he wants
Into a Textbox, you cannot be sure that the input text will be convertible to an instance of datetime or timespan. in this scenario, you can use the exceptionvalidationrule to report data conversion errors, and then display those conversion errors in the user
Interface. The XAML listed below demonstrates how to achieve this task.

     <Grid>        <Grid.RowDefinitions>            <RowDefinition />            <RowDefinition />            <RowDefinition />            <RowDefinition />            <RowDefinition />        </Grid.RowDefinitions>        <!-- START DATE -->        <TextBlock Grid.Row="0">Start Date:</TextBlock>        <TextBox Grid.Row="1">            <TextBox.Text>                <Binding Path="StartDate" UpdateSourceTrigger="PropertyChanged">                    <Binding.ValidationRules>                        <ExceptionValidationRule />                    </Binding.ValidationRules>                </Binding>            </TextBox.Text>        </TextBox>        <!-- DURATION -->        <TextBlock Grid.Row="2">Duration:</TextBlock>        <TextBox Grid.Row="3"                 Text="{Binding Path=Duration, UpdateSourceTrigger=PropertyChanged, ValidatesOnExceptions=True}"/>                <Button Grid.Row="4" Click="Button_Click">OK</Button>    </Grid>

Those two textboxes demonstrate the two ways that an exceptionvalidationrule can be added to the validationrules of a binding in XAML. The start date textbox uses the verbose property-element syntax to explicitly add the rule.
The duration textbox uses the shorthand syntax by simply setting the validatesonexceptions property of the binding to true. Both bindings have their updatesourcetrigger property set to propertychanged so that the input is validated every time the textbox's
Text property is given a new value, instead of waiting until the control loses focus. Figure 1Predictionvalidationrule displays validation errors


Displaying validation errorsas seen in Figure 1, The duration textbox contains an invalid value. The string it contains is not convertible to a timespan instance. the textbox's tooltip displays an error message, and a small
Red error icon appears on the right side of the control. This behavior does not happen automatically, but it is easy to implement and customize.

Render input validation errors to the user

     <Window.Resources>        <!--        The template which renders a TextBox        when it contains invalid data.        -->        <ControlTemplate x:Key="TextBoxErrorTemplate">            <DockPanel>                <Ellipse                    DockPanel.Dock="Right"                     Margin="2,0"                    ToolTip="Contains invalid data"                    Width="10" Height="10"                    >                    <Ellipse.Fill>                        <LinearGradientBrush>                            <GradientStop Color="#11FF1111" Offset="0" />                            <GradientStop Color="#FFFF0000" Offset="1" />                        </LinearGradientBrush>                    </Ellipse.Fill>                </Ellipse>                <!--                This placeholder occupies where the TextBox will appear.                -->                <AdornedElementPlaceholder />            </DockPanel>        </ControlTemplate>        <!--        The Style applied to both TextBox controls in the UI.        -->        <Style TargetType="TextBox">            <Setter Property="Margin" Value="4,4,10,4" />            <Setter                 Property="Validation.ErrorTemplate"                 Value="{StaticResource TextBoxErrorTemplate}"                 />            <Style.Triggers>                <Trigger Property="Validation.HasError" Value="True">                    <Setter Property="ToolTip">                        <Setter.Value>                            <Binding                                 Path="(Validation.Errors)[0].ErrorContent"                                RelativeSource="{x:Static RelativeSource.Self}"                                />                        </Setter.Value>                    </Setter>                </Trigger>            </Style.Triggers>        </Style>    </Window.Resources>

The static validation class forms a relationship between a control and any validation errors it contains by the use of some attached properties and static methods. You can reference those attached properties in XAML to create markup-only
Descriptions of how the user interface shocould present input validation errors to the user. The above XAML is responsible for explaining how to render input errors messages for the two textbox controls in the previous example.

The style targets all instances of a textbox In the UI. it applies three settings to a textbox. the first setter affects the textbox's margin property. the margin property is set to a value that provides enough
Space to display the error icon on the right side. the next setter in the style assigns the controltemplate used to render the textbox when it contains invalid data. it sets the attached validation. errortemplate property to the controltemplate declared above
Style. When the validation class reports that the textbox has one or more validation errors, the textbox renders with that template. This is where the red error icon comes from, as seen in
Figure 1. The style also contains a trigger that monitors the attached validation. haserror property on the textbox. When the validation class sets the attached haserror property to true for the textbox, the style's trigger
Activates and assigns a tooltip to the textbox. the content of the tooltip is bound to the error message of the exception thrown when attempting to parse the textbox's text into an instance of the source property's data type.


Input Validation via idataerrorinfoWith the introduction of the Microsoft. NET Framework 3.5, WPF support for Input Validation vastly improved. The validationrule approach is useful for simple applications, but real-world applications deal
The complexity of real-world data and business rules. encoding business rules into validationrule objects not only ties that code to the WPF platform, but it also does not allow for business logic to exist where it belongs: In business objects! Applications have a business layer, where the complexity of processing business rules is contained in a set of business objects. When compiling against the Microsoft. NET Framework 3.5, you can make use
The idataerrorinfo interface to have WPF ask Business Objects if they are in a valid State or not. this removes the need to place business logic in objects separate from the business layer, and it allows you to create UI platform-independent business objects.
Since the idataerrorinfo interface has been around for years, this also makes it much easier to reuse business objects from a legacy windows forms or ASP. NET application. suppose that you need to provide validation for an ERA beyond just ensuring that the user's text input is convertible to the source property's data type. it might make sense that an era's start date cannot be in
The future, since we do not know about ERAs that have yet to exist. it might also make sense to require that an era last for at least one millisecond. these types of rules are similar to the generic idea of business logic in that they are both examples of domain rules. it is best to implement domain rules in the objects that store their State: domain objects.
The Code listed below shows the smartid class, which exposes validation error messages via the idataerrorinfo interface.

public class SmartEra : Era , IDataErrorInfo    {        #region IDataErrorInfo Members        public string Error        {            get { return null; }        }        public string this[string property]        {            get            {                string msg = null;                switch (property)                {                    case "StartDate":                        if (DateTime.Now < this.StartDate)                            msg = "Start date must be in the past.";                        break;                    case "Duration":                        if (this.Duration.Ticks == 0)                            msg = "An era must have a duration.";                        break;                    default:                        throw new ArgumentException(                            "Unrecognized property: " + property);                }                return msg;            }        }        #endregion // IDataErrorInfo Members    }

Consuming the validation support of the smartid class from a WPF user interface is very simple. the only thing you have to do is tell the bindings that they shoshould honor the idataerrorinfo interface on the object to which they are bound. you can do this in
One of two ways, as below:

<!-- START DATE --><TextBlock Grid.Row="0">Start Date:</TextBlock><TextBox Grid.Row="1">  <TextBox.Text>    <Binding Path="StartDate" UpdateSourceTrigger="PropertyChanged">      <Binding.ValidationRules>        <ExceptionValidationRule />        <DataErrorValidationRule />      </Binding.ValidationRules>    </Binding>  </TextBox.Text></TextBox><!-- DURATION --><TextBlock Grid.Row="2">Duration:</TextBlock><TextBox   Grid.Row="3"   Text="{Binding          Path=Duration,          UpdateSourceTrigger=PropertyChanged,          ValidatesOnDataErrors=True,         ValidatesOnExceptions=True}"  />
Similar to how you can add the exceptionvalidationrule explicitly or implicitly to a binding's validationrules collection, you can add the dataerrorvalidationrule directly to the validationrules of a binding, or
You can just set the validatesondataerrors property to true. Both approaches result in the same net effect; the binding system queries the data source's idataerrorinfo interface for validation errors.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.