首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用CollectionView监听INotifyDataErrorInfo

如何使用CollectionView监听INotifyDataErrorInfo
EN

Stack Overflow用户
提问于 2016-08-17 22:20:11
回答 1查看 454关注 0票数 0

我有以下场景:

XAML:

代码语言:javascript
复制
<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是包含ListCollectionView的自定义ObservableCollection

代码语言:javascript
复制
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):

代码语言:javascript
复制
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

代码语言:javascript
复制
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的集合中

代码语言:javascript
复制
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

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

我的第一个直觉是,Node需要以某种方式订阅NodeResultsErrorsChanged事件并使其冒泡,因此在ObservableValidatableModelBase类上使用BubbleErrorsChanged方法-但这似乎不起作用。

另一种可能性是- ListView是否有用于显示验证异常的默认模板?如果不是,像这样的东西应该起作用吗?(它不...)

代码语言:javascript
复制
<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可以很好地工作,并给出我所期望的结果。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-08-17 23:16:56

我需要以下内容:

代码语言:javascript
复制
<ListView.ItemContainerStyle>
    <Style TargetType="ListViewItem">
        <Setter Property="Background" Value="{Binding Path=HasErrors, Mode=OneWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource BooleanToBrushConverter}}"/>
    </Style>
</ListView.ItemContainerStyle>  
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38999282

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档