Reputation: 231
I am relatively new to WPF and the MVVM model, but after hours of searching and reading articles regarding the matter, I have not come up with a definitive solution to this.
1) Model: I have an EF model relying on an SQL Express database. For this example, I will use a property named Visits, a DbSet(Of Visit).
2) ViewModel: an ObservableCollection(Of Visit). It is declared as such:
Private _Visits As ObservableCollection(Of Visit)
Public Property Visits As ObservableCollection(Of Visit)
Get
Return _Visits
End Get
Set(value As ObservableCollection(Of Visit))
_Visits = value
RaisePropertyChanged("Visits")
End Set
End Property
...
Visits = New ObservableCollection(Of Visit)(
From V In Application.context.Visits
Where V.IsRobotGenerated AndAlso
Not V.IsSynced
)
3) View: a WPF datagrid.
<DataGrid
x:Name="grdVisits"
ItemsSource="{
Binding Path=Visits,
RelativeSource={RelativeSource FindAncestor, AncestorType=Window}
}"
/>
Now I have a background thread which modifies the EF data directly (does all CRUD operations). What I want is the datagrid to reflect these changes as they happen.
What I am doing right now is replace the Visits ObservableCollection by re-calling the constructor above, which results to 2 drawbacks:
1) Performance wise I suppose it is not the best choice, especially when we are talking about quite a few thousands of rows (each with its RowDetails).
2) The user has in the meantime scrolled down the datagrid or opened a RowDetailsTemplate. His position and everything is lost if the entire collection is reset.
I have read somewhere about DependencyProperties but I do not have time to go through it thoroughly since I have no clue if it is a pointer to the right direction. If it is, I will be happy to do so.
Any help will be greatly appreciated.
Upvotes: 2
Views: 3371
Reputation: 5789
When you add or remove elements from an ObservableCollection
bound to an ItemsSource
, those changes are instantly reflected so what you need to do is simply to modify the ObservableCollection
accordingly as your CRUD operations take place.
Bear in mind that if you are using a version of .NET prior to 4.5 you'll need to dispatch the ObservableCollection
changes to the UI thread.
UPDATE: answering to the comment
What about the following scenario: two datagrids in the view, which are bound to two different ObservableCollections. However, these ObservableCollections are created with a different constructor so as to apply filtering to the underlying Visits. Can you provide a bare bones example as to how I can accomplish the aforementioned?
Filtering is a different story. It is supported by an intermediate layer set between your collection and the items control (ObservableCollection
and DataGrid
respectively in this case): collection views. Actually, you always bind to collection views, not to the collections directly.
So, for your scenario you'd bind both DataGrids
to the same underlying collection but using two different collection views, one for each DataGrid
. This way, the data stays the same and synchronized with whatever you need it to be (your CRUD operations for instance). However, each DataGrid
can display a subset of the data based on filtering, sorted and/or grouped in a different way.
I'd suggest you take a look into the MSDN article regarding data binding to collections.
Upvotes: 1