VB.NET中的WPF中的Observable Collection发生更改时,不会触发INotifyPropertyChanged事件 [英] INotifyPropertyChanged event not firing when Observable Collection changed in WPF in VB.NET

查看:339
本文介绍了VB.NET中的WPF中的Observable Collection发生更改时,不会触发INotifyPropertyChanged事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在WPF中使用带有MVVM模式的数据绑定.到目前为止,似乎一切都已正确地进行,并且我正在使用正确类型的类和对象.我的可观察集合首次加载正确,但是在数据网格更改时不会刷新. Observable Collections应该自动实现INPC,并且我还在基类中为其提供了处理程序,因此我感到困惑,为什么它仍然无法正常工作并更新我的UI.这是我的代码如下:

I'm trying to use databinding in WPF with an MVVM pattern. So far, it seems that everything is plumbed up properly and I'm using the right type of classes and objects. My observable collection loads to first time correctly, but won't refresh on the datagrid when it changes. Observable Collections should automatically implement INPC and I've also provided a handler for it in my base class, so I'm confused why it is still not working and updating my UI. Here's my code below:

ViewModelBase类:

ViewModelBase Class:

#Region "INotifyPropertyChanged Members"
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Protected Overridable Sub OnPropertyChanged(ByVal propertyName As String)
    VerifyPropertyName(propertyName)
    Dim handler As PropertyChangedEventHandler = PropertyChangedEvent
    If handler IsNot Nothing Then
        Dim e = New PropertyChangedEventArgs(propertyName)
        handler(Me, e)
    End If
End Sub
#End Region

MainWindowViewModel类:

MainWindowViewModel Class:

Public Class MainWindowViewModel
    Inherits ViewModelBase

    Private Shared _coreInfoData As ObservableCollection(Of Person)
    Public Shared Property CoreInfoData() As ObservableCollection(Of Person)
        Get
            Return _coreInfoData
        End Get
        Set(ByVal value As ObservableCollection(Of Person))
            _coreInfoData = value
        End Set

    Public Sub Main()
        If CoreInfoData IsNot Nothing Then
            CoreInfoData.Clear()
        End If
        CoreInfoData = GetRecords()
    End Sub

GetRecords函数是对数据库的调用,该数据库获取了最新的可用记录集.

The GetRecords function is a call to a database that gets the most recent set of records available.

在我看来,我实际上是绑定到CollectionViewSource并将其绑定到数据网格:

In my view, I'm actually binding to a CollectionViewSource and binding that to a datagrid:

<UserControl.Resources>
    <CollectionViewSource Source="{Binding Path=CoreInfoData, Mode=TwoWay}" x:Key="cvs">
        <CollectionViewSource.GroupDescriptions>
            <dat:PropertyGroupDescription PropertyName="GroupId"/>
        </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>
</UserControl.Resources>
<DataGrid ItemsSource="{Binding Source={StaticResource cvs}}" AutoGenerateColumns="False" >
    <DataGrid.Columns>
        <DataGridTextColumn Header="Last Name" Binding="{Binding Path=LastName}" IsReadOnly="True" />
        <DataGridTextColumn Header="First Name" Binding="{Binding Path=FirstName}" IsReadOnly="True"/>
    </DataGrid.Columns>
</DataGrid>

Person类具有属性LastNameFirstName(还有其他属性).据我了解,如果ObservableCollection本身发生了变化-就像我通过清除并填充备份所做的那样,它将自动触发INPC事件,但我的DataGrid似乎第二次没有刷新.任何想法都会很有帮助.

The Person class has properties LastName and FirstName (amoung others). As I understand it, if the ObservableCollection itself changes - like what I do by clearning and filling it back up, it should automatically fire the INPC event, but my DataGrid doesn't seem to refresh the second time around. Any ideas would be really helpful.

谢谢!

* EDIT * 这是我解决问题的方法:

*EDIT* Here's how I wound up solving the problem:

以ObservableCollection(Of Person)作为公共共享属性CoreInfoData()

Public Shared Property CoreInfoData() As ObservableCollection(Of Person)

Public Shared Property CoreInfoData() As ObservableCollection(Of Person)
    Get
        Return _coreInfoData
    End Get
    Set(ByVal value As ObservableCollection(Of Person))
        If _coreInfoData Is Nothing Then
            'get data
             _coreInfoData = value
        Else
             'refresh data
             _coreInfoData.Clear()
              For i = 0 To value.Count - 1
                    _coreInfoData.Add(value(i))
              Next
        End If
    End Set
End Property

首次调用Set方法时,它将创建一个新的_coreInfoData变量.随后的调用将通过清除其全部内容并循环遍历每个项目以将其添加回集合中来替换现有的. 感谢Clemens,Dan Busha和Charleh(和其他人)的有用评论!

The First time the Set Method is called it will create a new _coreInfoData variable. Subsequent calls will replace the existing one by clear it's entire contents and looping through each item to add it back into the collection. Thanks to Clemens, Dan Busha, and Charleh (and others) for their helpful comments!

推荐答案

仅由于属性的类型为ObservableCollection,不会自动引发PropertyChanged事件.您将不得不在二传手中提出它:

No PropertyChanged event will be raised automatically simply because the type of a property is ObservableCollection. You would have to raise it in the setter:

Set(ByVal value As ObservableCollection(Of Person)) 
    _coreInfoData = value
    OnPropertyChanged("CoreInfoData")
End Set 

这篇关于VB.NET中的WPF中的Observable Collection发生更改时,不会触发INotifyPropertyChanged事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆