Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Data validation in WPF

0.00/5 (No votes)
5 Feb 2014 1  
how to implement data validation via regular expressions in a WPF application

Starting with the model

After adding a table (conversation topics) in the model in the data layer, I created a partial public class of that table. This class has to implement iDataErrorInfo and you can add the following code:

#Region "IDataErrorInfo Members"
    Private m_validationErrors As New Dictionary(Of String, String)
 
    Private Sub AddError(ByVal columnName As String, ByVal msg As String)
        If Not m_validationErrors.ContainsKey(columnName) Then
            m_validationErrors.Add(columnName, msg)
        End If
    End Sub
 
    Private Sub RemoveError(ByVal columnName As String)
        If m_validationErrors.ContainsKey(columnName) Then
            m_validationErrors.Remove(columnName)
        End If
    End Sub
 
    Public ReadOnly Property HasErrors() As Boolean
        Get
            Return m_validationErrors.Count > 0
        End Get
    End Property
 
    Public ReadOnly Property [Error] As String Implements System.ComponentModel.IDataErrorInfo.Error
        Get
            If m_validationErrors.Count > 0 Then
                Return "Customer data is invalid"
            Else
                Return Nothing
            End If
        End Get
    End Property
 
    Default Public ReadOnly Property Item(ByVal columnName As String) As String Implements System.ComponentModel.IDataErrorInfo.Item
        Get
            If m_validationErrors.ContainsKey(columnName) Then
                Return m_validationErrors(columnName).ToString
            Else
                Return Nothing
            End If
        End Get
    End Property
 
#End Region

Add the onchanged event of the field that should be validated

Private Sub OnlConTopFChanged()
        _regex = New Regex("([A-Za-z0-9-]+)", RegexOptions.IgnoreCase)
        If _lConTopF Is Nothing OrElse Not _regex.Match(_lConTopF.ToString()).Success Then
            Me.AddError("lConTopF", "Fill in a value.")
        Else
            Me.RemoveError("lConTopF")
        End If
    End Sub
 
    Private Sub OnlConTopNChanged()
        _regex = New Regex("([A-Za-z0-9-]+)", RegexOptions.IgnoreCase)
        If _lConTopN Is Nothing OrElse Not _regex.Match(_lConTopN.ToString()).Success Then
            Me.AddError("lConTopN", "Fill in a value.")
        Else
            Me.RemoveError("lConTopN")
        End If
    End Sub

Continue with the User interface

Make sure to bind you control to the correct field (in our case lConTopF and lConTopN) Add ValidatesOnDataErrors = true to make it validate Add UpdateSourceTrigger=propertychanged to make sure it validates everytime the value changes

       <TextBox Name="txtNameNL"
                     Grid.Row="1"
                     Grid.Column="1"
                     Margin="5"
                     Text="{Binding Path=ObsConTop.ConTop.lConTopN,
                                    ValidatesOnDataErrors=True,
                                    UpdateSourceTrigger=PropertyChanged}" />
            <TextBox Name="txtNameFR"
                     Grid.Row="2"
                     Grid.Column="1"
                     Margin="5"
                     Text="{Binding Path=ObsConTop.ConTop.lConTopF,
                                    ValidatesOnDataErrors=True,
                                    UpdateSourceTrigger=PropertyChanged}" />

Set a general style for indicating an error

You can do this in Application.Xaml:

	<Style x:Key="myErrorTemplate" TargetType="Control">
                <Setter Property="Validation.ErrorTemplate">
                    <Setter.Value>
                        <ControlTemplate>
                            <DockPanel LastChildFill="True">
                                <Ellipse Width="15"
                                         Height="15"
                                         Margin="-25,0,0,0"
                                         DockPanel.Dock="Right"
                                         Fill="Red"
                                         StrokeThickness="1"
                                         ToolTip="{Binding ElementName=myTextbox,
                                                           Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
                                    <Ellipse.Stroke>
                                        <LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
                                            <GradientStop Offset="0" Color="#FFFA0404" />
                                            <GradientStop Offset="1" Color="#FFC9C7C7" />
                                        </LinearGradientBrush>
                                    </Ellipse.Stroke>
                                </Ellipse>
                                <TextBlock Margin="-15,5,0,0"
                                           DockPanel.Dock="Right"
                                           FontSize="9pt"
                                           FontWeight="Bold"
                                           Foreground="White"
                                           ToolTip="{Binding ElementName=myControl,
                                                             Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
                                    !
                                </TextBlock>
                                <Border BorderBrush="Red" BorderThickness="1">
                                    <AdornedElementPlaceholder Name="myControl" />
                                </Border>
                            </DockPanel>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
                <Style.Triggers>
                    <Trigger Property="Validation.HasError" Value="true">
                        <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}" />
                    </Trigger>
                </Style.Triggers>
            </Style>
            <Style BasedOn="{StaticResource myErrorTemplate}" TargetType="TextBox" />
            <Style BasedOn="{StaticResource myErrorTemplate}" TargetType="CheckBox" />
            <Style BasedOn="{StaticResource myErrorTemplate}" TargetType="ComboBox" />

Result


License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here