0

我有以下情况:

XAML:

<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}">

其中 Nodes 是ObservableCollection包含 ListCollectionView 的自定义:

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在这种情况下是一个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

我想要发生的是让Nodes 中的个人CollectionView通知,以便它在屏幕上ListView突出显示无效的个人条目(即具有无效的 a )。NodeResults

我的第一直觉是 Node 需要以某种方式订阅和冒泡NodeResults'ErrorsChanged事件,因此类BubbleErrorsChanged上的方法ObservableValidatableModelBase- 但这似乎不起作用。

另一种可能性是 - ListView 是否甚至有用于显示验证异常的默认模板?如果没有,这样的事情应该有效吗?(它没有……)

<ListView.ItemContainerStyle>
    <Style TargetType="ListViewItem">
        <Setter Property="Background" Value="{Binding Path=(Validation.Errors).CurrentItem, Converter={StaticResource ValidationExceptionToColourConverter}}"/>
     </Style>
 </ListView.ItemContainerStyle>

ValidationExceptionToColourConverter根据错误是否存在,只需返回 Brushes.Red 或 Brushes.White即可Nothing

注意:将文本框直接绑定到 Nodes.NodeResults.SomeProperty 可以正常工作,给出我期望的结果。

4

1 回答 1

0

我需要以下内容:

<ListView.ItemContainerStyle>
    <Style TargetType="ListViewItem">
        <Setter Property="Background" Value="{Binding Path=HasErrors, Mode=OneWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource BooleanToBrushConverter}}"/>
    </Style>
</ListView.ItemContainerStyle>  
于 2016-08-17T15:16:56.273 回答