I used Drag and Drop to bind Data Source object (a DB model) to DataGrid
(basically following this example in Entity Framework Databinding with WPF.
Everything works fine with this implementation.
XAML
<Window.Resources>
<CollectionViewSource x:Key="categoryViewSource"
d:DesignSource="{d:DesignInstance {x:Type local:Category}, CreateList=True}"/>
</Window.Resources>
<Grid DataContext="{StaticResource categoryViewSource}">
..
Code Behind
private void Window_Loaded(object sender, RoutedEventArgs e)
{
System.Windows.Data.CollectionViewSource categoryViewSource =
((System.Windows.Data.CollectionViewSource)(this.FindResource("categoryViewSource")));
_context.Categories.Load();
categoryViewSource.Source = _context.Categories.Local;
}
ViewModel
public MainWindow()
{
InitializeComponent();
this.DataContext = new MyViewModel();
}
However, when I try to use the same code from within ViewModel, it doesn‘t work (FindResource
is not available), besides, I don’t think this is the right approach (i.e. to use x:Key
in MVVM).
I would really appreciate any help to point me what is the right way to implement CollectionViewSource
and DataBinding
with DataGrid
.
You have two options to use
CollectionViewSource
properly with MVVM -Expose an
ObservableCollection
of items (Categories
in your case) through yourViewModel
and createCollectionViewSource
in XAML like this -scm:
xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
see this -
Filtering
collections from XAML using CollectionViewSourceCreate and Expose an
ICollectionView
directly from yourViewModel
see this - How to Navigate, Group, Sort and Filter Data in WPF
Following example shows how to create a collection view and bind it to a
ListBox
View XAML:
View Codebehind:
ViewModel:
Just for reference, another way is to use an attached property on the CollectionViewSource which then pipes the functions to the ViewModel (Implementing an Interface).
This is a very basic Demonstration just for filtering, it would need some work for e.g. a second Collection on the VM but i think it's enough to show the general technique.
If this is better or worse than the other methods is up for discussion, i just wanted to point out, that there's another way of doing this
Definition of attached Property:
Interface:
usage in xaml:
and usage in the ViewModel:
I found that it is handy to have a
CollectionViewSource
in my ViewModel and bind theListBox
(in my case) to theCollectionViewSource.View
while setting theCollectionViewSource.Source
to be the list I want to use.Like so:
ViewModel:
XAML:
This means I can do neat stuff in the VM as needed (from https://blogs.msdn.microsoft.com/matt/2008/08/28/collectionview-deferrefresh-my-new-best-friend/ ):
I suppose this is possible when using the
ICollectionView
object also, but the demo code in the blog link seems to be some codebehind stuff, refering the listbox directly, which I'm trying to avoid.BTW before you ask, here's how you use a Design Time VM: WPF Design Time View Model