0

를 사용하여 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 구현합니다 INotifyDataErrorInfoerrors라는 컬렉션의 오류를 저장합니다

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> 
:

답변

관련 문제