In my View I got a ListView bound to a CollectionView in my ViewModel, for example like this:
<ListView ItemsSource="{Binding MyCollection}" IsSynchronizedWithCurrentItem="true">
<ListView.View>
<GridView>
<GridViewColumn Header="Title" DisplayMemberBinding="{Binding Path=Title}"/>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Path=Name}"/>
<GridViewColumn Header="Phone" DisplayMemberBinding="{Binding Path=Phone}"/>
<GridViewColumn Header="E-mail" DisplayMemberBinding="{Binding Path=EMail}"/>
</GridView>
</ListView.View>
</ListView>
Right now these GridViewColumns are fixed, but I'd like to be able to change them from the ViewModel. I'd guess I'll have to bind the GridViewColumn-collection to something in the ViewModel, but what, and how?
The ViewModel does know nothing of WPF, so I got no clue how to achieve this in MVVM.
any help here?
I took Thomas Levesque's excellent solution and modified it to remove the static collection of GridViews and also add the ability to set a column width and string format, so thought I'd share my code.
Modified attached property class:
Behaviour (this is stored against each GridView and obviates the need to store the collection-GridView mappings centrally):
I think this code would cause some memory leak issues; As your class GridViewColumns described, you've defined a static dictionary "_gridViewsByColumnsSource" in which contains the gridviews and their columns source references; so this is a strong reference to the added gridviews and columns source; Because this dictionary is static, it seems that there's a static reference "point" to the gridviews and columns source data all the time, if the screen in which the gridview defined closed, the gridview cannot be collected by GC if GC is started; As more and more similar screens opened, more and more gridviews and its columns source data cannot be collected, there'll be memory leak at the end.
The
Columns
property is not a dependency property, so you can't bind it. However, it might be possible to create an attached property that you could bind to a collection in your ViewModel. This attached property would then create the columns for you.UPDATE
OK, here's a basic implementation...
Attached properties
ViewModel
XAML :
Note that the
ColumnDescriptor
class is not actually needed, I only added it for clarity, but any type will do (including an anonymous type). You just need to specify which properties hold the header text and display member name.Also, keep in mind that it's not fully tested yet, so there might be a few problems to fix...