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
I've been a developer since the late 90's, going from Mainframe to Object Oriented. I'm in a small team, developing inhouse WPF applications, used for commercial support.
I'll try to share information and tips and tricks for developing in WPF, explain how we solved issues, what we did to meet our goal.
If you have any questions, remarks, suggestions... please let me know !
regs,
Wim