我有以下ViewModel,使用ItemsSource="{Binding Path=ItemsViewSource.View}"
绑定到我视图中的DataGrid:
Public Class DataTableViewModel
Inherits ViewModelBase
Private _dataContext As DbContext
Private _items As IList
Private _itemsType As Type
Private _contextType As Type
Private _itemsViewSource As CollectionViewSource
Private _itemsView As ListCollectionView
'Commands
Private _refreshTableCommand As ICommand
Public ReadOnly Property RefreshTableCommand As ICommand
Get
If _refreshTableCommand Is Nothing Then
_refreshTableCommand = New RelayCommand(AddressOf ExecuteRefreshTable, AddressOf CanExecuteRefreshTable)
End If
Return _refreshTableCommand
End Get
End Property
Private Function CanExecuteRefreshTable() As Boolean
'This command can always run.
Return True
End Function
Private Sub ExecuteRefreshTable()
Me.RefreshTable()
End Sub
Public Property Items As IList
Get
Return Me._items
End Get
Set(value As IList)
_items = value
MyBase.OnPropertyChanged("Items")
End Set
End Property
Public Property ItemsViewSource As CollectionViewSource
Get
Return Me._itemsViewSource
End Get
Set(value As CollectionViewSource)
Me._itemsViewSource = value
MyBase.OnPropertyChanged("ItemsViewSource")
End Set
End Property
Public Property ItemsView As ListCollectionView
Get
Return Me._itemsView
End Get
Set(value As ListCollectionView)
Me._itemsView = value
MyBase.OnPropertyChanged("ItemsView")
End Set
End Property
Public ReadOnly Property DataContext As DbContext
Get
Return Me._dataContext
End Get
End Property
Public ReadOnly Overrides Property IsDirty As Boolean
Get
Return Me._dataContext.ChangeTracker.HasChanges
End Get
End Property
Private Sub RefreshTable()
NewDataContext()
End Sub
Private Sub NewDataContext()
If Me._dataContext IsNot Nothing Then
Me._dataContext.Dispose()
End If
Me._dataContext = Activator.CreateInstance(_contextType)
Me._dataContext.Set(_itemsType).Load
Me.Items = _dataContext.Set(_itemsType).Local
End Sub
Public Sub New(displayName As String, contextType As Type, recordType As Type)
MyBase.DisplayName = displayName
Me._itemsType = recordType
Me._contextType = contextType
NewDataContext()
Me._itemsViewSource = New CollectionViewSource
Me.ItemsViewSource.Source = Me.Items
Me.ItemsView = CType(Me.ItemsViewSource.View, ListCollectionView)
Me.ItemsView.Filter = New Predicate(Of Object)(AddressOf FilterByString)
End Sub
End Class
代码完美运行,直到调用RefreshTable()
方法,此时数据绑定似乎中断。来自数据库的任何新数据都加载到ViewModel中,并且可以在Items列表中使用,但新数据不会显示在datagrid中,并且用户在DataGrid中所做的任何更改都不会反映在DBContext.ChangeTracker。
我错过了什么?
修改 经过进一步测试,问题似乎与CollectionViewSource有某种关系;如果我直接绑定到Items属性,更新的记录将在DataGrid中正确显示。
答案 0 :(得分:0)
显然我一直盯着屏幕太久了。 还需要重建CollectionViewSource,并通过OnPropertyChanged(“ItemsViewSource”)通知DataGrid。
修正:
Private Sub RefreshTable()
NewDataContext()
Me._itemsViewSource = New CollectionViewSource
Me.ItemsViewSource.Source = Me.Items
Me.ItemsView = CType(Me.ItemsViewSource.View, ListCollectionView)
Me.ItemsView.Filter = New Predicate(Of Object)(AddressOf FilterByString)
'Let WPF know the data changed in the ViewModel
OnPropertyChanged("ItemsViewSource")
End Sub