를 사용하여 INotifyDataErrorInfo을 청취하는 방법은 다음과 같은 시나리오를 가지고 :CollectionView
XAML :
Public Class FilterableObservableCollection(Of T)
Inherits ObservableCollection(Of T)
Implements INotifyPropertyChanged, INotifyCollectionChanged
Public Property CollectionView As ListCollectionView
Get
Return _collectionView
End Get
Protected Set(value As ListCollectionView)
If value IsNot _collectionView Then
_collectionView = value
NotifyPropertyChanged()
End If
End Set
End Property
'etc.
T
의 : 노드가 ListCollectionView를 포함 된 사용자 지정 ObservableCollection
입니다
<ListView Name="lsv_edit_selectNode" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="4"
Grid.RowSpan="17" IsSynchronizedWithCurrentItem="True" SelectionMode="Single"
ItemsSource="{Binding Path=Nodes.CollectionView, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnNotifyDataErrors=True}">
이 경우는 Node
객체이며, 관심있는 객체 (NodeResults라고 함)를 포함한 많은 속성이 있습니다.
Public Class Node
Inherits ObservableValidatableModelBase
Public Property NodeResults as NodeResults
Set
SetAndNotify(_nodeResults, Value) ' INotifyPropertyChanged
AddHandler _nodeResults.ErrorsChanged, AddressOf BubbleErrorsChanged ' INotifyDataErrorInfo?
End Set
End Property
' etc.
및 NodeResults
:
Public Class NodeResults
Inherits ObservableValidatableModelBase
' many properties here, each validated using custom Data Annotations. This works, when I bind a text box directly to here, for example.
ObservableValidatableModelBase
구현합니다 INotifyDataErrorInfo
및 errors
라는 컬렉션의 오류를 저장합니다
Private errors As New Dictionary(Of String, List(Of String))()
Public ReadOnly Property HasErrors As Boolean Implements INotifyDataErrorInfo.HasErrors
Get
Return errors.Any(Function(e) e.Value IsNot Nothing AndAlso e.Value.Count > 0)
End Get
End Property
Public Function GetErrors(propertyName As String) As IEnumerable Implements INotifyDataErrorInfo.GetErrors
Try
If Not String.IsNullOrEmpty(propertyName) Then
If If(errors?.Keys?.Contains(propertyName), False) _
AndAlso If(errors(propertyName)?.Count > 0, False) Then ' if there are any errors, defaulting to false if null
Return errors(propertyName)?.ToList() ' or Nothing if there are none.
Else
Return Nothing
End If
Else
Return errors.SelectMany(Function(e) e.Value.ToList())
End If
Catch ex As Exception
Return New List(Of String)({"Error getting errors for validation: " & ex.Message})
End Try
End Function
Public Event ErrorsChanged As EventHandler(Of DataErrorsChangedEventArgs) Implements INotifyDataErrorInfo.ErrorsChanged
Public Sub NotifyErrorsChanged(propertyName As String)
ErrorsChangedEvent?.Invoke(Me, New DataErrorsChangedEventArgs(propertyName))
End Sub
Public Sub BubbleErrorsChanged(sender As Object, e As DataErrorsChangedEventArgs)
If TypeOf (sender) Is ObservableValidatableModelBase Then
errors = DirectCast(sender, ObservableValidatableModelBase).errors
End If
NotifyErrorsChanged(String.Empty)
End Sub
내가 일이 원하는 것은 개별 Node
의에서입니다 은 ListView
을 알리기 위해 개인 정보를 강조 표시합니다. 알 수없는 항목 (예 : 유효하지 않은 NodeResults
있습니다).
나의 첫번째 본능 노드가 어떻게 든 거품에 NodeResults
'ErrorsChanged
이벤트는 ObservableValidatableModelBase
클래스에 따라서 BubbleErrorsChanged
방법을 가입 할 필요가 있다는 것이다 - 그러나 그것은 작동하지 않습니다.
또 다른 가능성은 - ListView에 유효성 검사 예외를 표시하기위한 기본 템플릿이 있습니까? 그렇지 않다면이 작품과 같은 것이 있어야합니까? (가 ...하지 않습니다)
ValidationExceptionToColourConverter
단순히 Brushes.Red 또는 Brushes.White 오류가
Nothing
여부에 따라 반환
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Background" Value="{Binding Path=(Validation.Errors).CurrentItem, Converter={StaticResource ValidationExceptionToColourConverter}}"/>
</Style>
</ListView.ItemContainerStyle>
.
참고 : 텍스트 상자를 Nodes.NodeResults.SomeProperty에 직접 바인딩하면 정상적으로 작동하여 예상 한 결과를 얻을 수 있습니다.
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Background" Value="{Binding Path=HasErrors, Mode=OneWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource BooleanToBrushConverter}}"/>
</Style>
</ListView.ItemContainerStyle>
: