我正在尝试在具有 MVVM 模式的 WPF 中使用数据绑定。到目前为止,似乎一切都已正确完成,并且我使用了正确类型的类和对象。我的可观察集合首次正确加载,但在数据网格更改时不会刷新。Observable Collections 应该自动实现 INPC,并且我还在我的基类中为它提供了一个处理程序,所以我很困惑为什么它仍然无法工作并更新我的 UI。下面是我的代码:
视图模型基类:
#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 类:
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 函数是对获取最新可用记录集的数据库的调用。
在我看来,我实际上是绑定到 CollectionViewSource 并将其绑定到数据网格:
<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 似乎没有第二次刷新。任何想法都会非常有帮助。
谢谢!
*编辑* 以下是我解决问题的方法:
公共共享属性 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(和其他人)的有益评论!