VB.NET中的WPF中的Observable Collection发生更改时,不会触发INotifyPropertyChanged事件 [英] INotifyPropertyChanged event not firing when Observable Collection changed in WPF in VB.NET
问题描述
我试图在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
类具有属性LastName
和FirstName
(还有其他属性).据我了解,如果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屋!