Alessandro Del Sole's Blog

{ A programming space about Microsoft® .NET® }
posts - 1909, comments - 2047, trackbacks - 352

My Links

News

Your host

This is me! Questo spazio è dedicato a Microsoft® .NET®, di cui sono molto appassionato :-)

Cookie e Privacy

Disabilita cookie ShinyStat

Microsoft MVP

My MVP Profile

Microsoft Certified Professional

Microsoft Specialist

Xamarin Certified Mobile Developer

Il mio libro su VB 2015!

Pre-ordina il mio libro su VB 2015 Pre-ordina il mio libro "Visual Basic 2015 Unleashed". Clicca sulla copertina per informazioni!

Il mio libro su WPF 4.5.1!

Clicca sulla copertina per informazioni! E' uscito il mio libro "Programmare con WPF 4.5.1". Clicca sulla copertina per informazioni!

These postings are provided 'AS IS' for entertainment purposes only with absolutely no warranty expressed or implied and confer no rights.
If you're not an Italian user, please visit my English blog

Le vostre visite

I'm a VB!

Guarda la mia intervista a Seattle

Follow me on Twitter!

Altri spazi

GitHub
I miei progetti open-source su GitHub

Article Categories

Archives

Post Categories

Image Galleries

Privacy Policy

WPF 4.5: INotifyDataErrorInfo

WPF 4.5 introduce una significativa novità nella validazione dei dati, costituita dall'interfaccia INotifyDataErrorInfo. Questa proviene da Silverlight e la sua peculiarità è quella di poter validare i dati anche in modalità asincrona (es. nell'ambito di callback).

Tale interfaccia ha tre membri fondamentali da implementare:

  • la proprietà HasErrors, di tipo booleano, che restituisce vero o falso a seconda che per la proprietà specificata esistano o meno errori di validazione
  • il metodo GetErrors che restituisce una IEnumerable di errori di validazione che colpiscono la proprietà specificata
  • l'evento ErrorsChanged, che va scatenato quando la collezione di errori viene modificata

Il seguente esempio (tratto da MSDN per Silverlight) mostra come implementare l'interfaccia e come aggiungere o rimuovere, da una collection di tipo Dictionary, voci costituenti errori di validazione attraverso due metodi chiamati AddError e RemoveError:

Imports System.ComponentModel
 
Public Class Product
    Implements INotifyDataErrorInfo
 
    Private idValue As Integer
    Public Property Id As Integer
        Get
            Return idValue
        End Get
        Set(ByVal value As Integer)
            If IsIdValid(value) AndAlso
                idValue <> value Then idValue = value
        End Set
    End Property
 
    Private nameValue As String
    Public Property Name As String
        Get
            Return nameValue
        End Get
        Set(ByVal value As String)
            If IsNameValid(value) AndAlso
                nameValue <> value Then nameValue = value
        End Set
    End Property
 
    ' Validates the Id property, updating the errors collection as needed.
    Public Function IsIdValid(ByVal value As IntegerAs Boolean
 
        Dim isValid = True
 
        If value < 5 Then
            AddError("Id", ID_ERROR, False)
            isValid = False
        Else
            RemoveError("Id", ID_ERROR)
        End If
 
        If value > 10 Then
            AddError("Id", ID_WARNING, True)
        Else
            RemoveError("Id", ID_WARNING)
        End If
 
        Return isValid
 
    End Function
 
    ' Validates the Name property, updating the errors collection as needed.
    Public Function IsNameValid(ByVal value As StringAs Boolean
 
        Dim isValid = True
 
        If value.Contains(" "Then
            AddError("Name", NAME_ERROR, False)
            isValid = False
        Else
            RemoveError("Name", NAME_ERROR)
        End If
 
        If (value.Length > 5) Then
            AddError("Name", NAME_WARNING, True)
        Else
            RemoveError("Name", NAME_WARNING)
        End If
 
        Return isValid
 
    End Function
 
    Private errors As New Dictionary(Of StringList(Of String))
    Private ReadOnly ID_ERROR As String = "Value cannot be less than 5."
    Private ReadOnly ID_WARNING As String = "Value should not be less than 10."
    Private ReadOnly NAME_ERROR As String = "Value must not contain any spaces."
    Private ReadOnly NAME_WARNING As String = "Value should be 5 characters or less."
 
    ' Adds the specified error to the errors collection if it is not 
    ' already present, inserting it in the first position if isWarning is 
    ' false. Raises the ErrorsChanged event if the collection changes. 
    Public Sub AddError(ByVal propertyName As StringByVal [error] As String,
                        ByVal isWarning As Boolean)
 
        If Not errors.ContainsKey(propertyName) Then _
            errors(propertyName) = New List(Of String)()
 
        If Not errors(propertyName).Contains([error]) Then
            If isWarning Then
                errors(propertyName).Add([error])
            Else
                errors(propertyName).Insert(0, [error])
            End If
            RaiseErrorsChanged(propertyName)
        End If
 
    End Sub
 
    ' Removes the specified error from the errors collection if it is
    ' present. Raises the ErrorsChanged event if the collection changes.
    Public Sub RemoveError(ByVal propertyName As StringByVal [error] As String)
 
        If errors.ContainsKey(propertyName) AndAlso
            errors(propertyName).Contains([error]) Then
 
            errors(propertyName).Remove([error])
            If errors(propertyName).Count = 0 Then errors.Remove(propertyName)
            RaiseErrorsChanged(propertyName)
 
        End If
 
    End Sub
 
    Public Sub RaiseErrorsChanged(ByVal propertyName As String)
        RaiseEvent ErrorsChanged(Me,
            New DataErrorsChangedEventArgs(propertyName))
    End Sub
 
    Public Event ErrorsChanged As EventHandler(Of DataErrorsChangedEventArgs) _
        Implements INotifyDataErrorInfo.ErrorsChanged
 
    Public Function GetErrors(ByVal propertyName As String) _
        As System.Collections.IEnumerable _
        Implements INotifyDataErrorInfo.GetErrors
        Return errors(propertyName)
    End Function
 
    Public ReadOnly Property HasErrors As Boolean _
        Implements INotifyDataErrorInfo.HasErrors
        Get
            Return errors.Any
        End Get
    End Property
 
End Class

 Lato XAML l'accortezza che bisogna avere è quella di impostare a True l'espressione NotifyOnValidationError:

    <StackPanel>
        <TextBox Text="{Binding Path=Id, Mode=TwoWay, NotifyOnValidationError=True}" Margin="5"/>
        <TextBox Text="{Binding Path=Name,Mode=TwoWay,NotifyOnValidationError=True}" Margin="5"/>
    </StackPanel>

Chiaramente WPF utilizza un template di default per la visualizzazione degli errori, per cui un errore verrebbe evidenziato in questo modo:

Come però sapete è possibile ridefinire l'ErrorTemplate delle TextBox e presentare gli errori in modo anche diverso.

Alessandro

Print | posted on lunedì 20 febbraio 2012 18:23 | Filed Under [ Windows Presentation Foundation ]

Powered by:
Powered By Subtext Powered By ASP.NET