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