Search code examples
vb.netdata-bindinginotifypropertychangedidataerrorinfo

How to get IDataErrorInfo to propagate error messages from class to the UI?


I'm using VB.NET 2012 the project type is (Windows Form Application) not a (WPF Application)

The From's load event creates a Data Binding between a TextBox and the "Age" property in Class1

Public Class Form1
Private _Class1 As New Class1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
        Me.TextBox1.DataBindings.Add("Text", _Class1, "Age", False, DataSourceUpdateMode.OnPropertyChanged)
    End Sub
End Class

As the Text property of TextBox1 changes, so does the 'Age' Property in Class1 below, the Age Property stays synchronized with what is displayed in the UI via INotifyPropertyChanged, if something else changes the Age property, for example the SetVal procedure at the bottom of Class1, the change is propagated back to the UI

The problem I’m having is getting the IDataErrorInfo to work in a similar way where errors can be propagated back to the UI, preferably like an ErrorProvider where a little red dot is at the right of TextBox1? Cannot find a VB example that that is clear on this. Can anyone help?

Imports System.ComponentModel

Public Class Class1
    Implements INotifyPropertyChanged, IDataErrorInfo

    Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged

    Private m_age As Integer
    Public Property Age() As Integer
        Get
            Return m_age
        End Get
        Set(ByVal value As Integer)
            m_age = value
            OnPropertyChanged("Age")
        End Set
    End Property

    Public ReadOnly Property [Error]() As String Implements IDataErrorInfo.Error
        Get
            Return ""
        End Get
    End Property
    Default Public ReadOnly Property Item(ByVal name As String) As String Implements IDataErrorInfo.Item
        Get
            Dim result As String = Nothing
            If name = "Age" Then
                If Me.m_age < 0 OrElse Me.m_age > 150 Then
                    result = "Age must not be less than 0 or greater than 150."
                    ' NOTE: Flow arrives here but nothing happens, nothing is sent back to the form, 
                    ' I want this to trigger the displaying of an ErrorProvider, next to TextBox1 in the UI
                    Debug.WriteLine(m_age.ToString)
                End If
            End If
            Return result
        End Get
    End Property


    Private Sub OnPropertyChanged(Name As String)
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(Name))
    End Sub

    Public Sub SetVal()
        Age = 0  ' NOTE: this works, the value is propagated back to the form's TextBox1
    End Sub

End Class

Solution

  • A coworker shared this with me. All I was missing was an Error Provider with it's DataSource set = to _Class1. . . Now the error conditions dynamically propagate back the Text control without any extra code

    Public Class Form1
    
    Private _Class1 As New Class1
    Private errorProv As New ErrorProvider ' ** Here
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
            Me.TextBox1.DataBindings.Add("Text", _Class1, "Age", False,     DataSourceUpdateMode.OnPropertyChanged)
            errorProv.ContainerControl = Me ' ** Here
            errorProv.DataSource = _Class1  ' ** and Here
        End Sub
    End Class