Reputation: 441
I'm relatively new to WPF and I am trying to make a control where I display data from multiple source objects. The source objects are stored in a collection in my view model and each item has a name and a collection of data objects. Each data object has some properties representing it. The data structure looks something like this:
In the view model
ObservableCollection<MySourceObjectType> sourceItems {get; set;}
MySourceObjectType:
SomeType Name {get; set;}
SomeType Number {get; set;}
IList<MyDataObjectType> {get; set;}
MyDataObjectType:
SomeType data1 {get; set;}
SomeType data2 {get; set;}
SomeType data3 {get; set;}
I want my grid to look something like this:
In addition to that layout, the control needs to support reordering the column groups that correspond to each source object and all rows need to scroll vertically together as if they were all in the same datagrid. The column and group headers also need to be frozen to the top so that they are visible regardless of the scroll position. The individual columns should not be able to be reordered relative to one another and the column groups must always stay together. The source items can be an arbitrarily sized collection so I can't predefine the groups, but the columns within each group are predefined and won't change.
Currently I have this working by using a ListBox
with its ItemSource
bound to sourceItems. The ItemsPanel
is a dockpanel with a text box for the super header and a datagrid to display the data for each item. I can reorder them with drag and drop with a bunch of event handlers and I synced the scrolling with event handlers as well. The reordering currently is getting a reference to the source collection and reordering that when the drop happens which violates the mvvm.
I want to know if there is a better, cleaner way to do this other than using a separate DataGrid
for each item. I have played around with having auto generated columns for each item and then the cell template would be another DataGrid. I couldn't figure out how to make it work and doesn't seem any better other than the group reordering being taken care of by the DataGrid itself.
My current thought is that I will have to create a custom control for a GroupedDataGrid or whatever and give it the ability to reorder groups, but I'd definitely be interested in an easier way to accomplish the task.
My basic requirements are that it must follow strict MVVM and my main xaml layout can have no code behind. I imagine if the code behind is minimal and purely UI manipulation I can squeak it by, but no code behind is ideal.
Any ideas?
Upvotes: 4
Views: 2816
Reputation: 12533
This would be a partial answer since providing an implementation would take some time , how ever since this is of interest to me i'll attempt to supply you with an implementation later on .
What you need to do would involve using grouping ,
Add some common property to your objects which distinguishes them into groups for example
public Type GroupType
{
return typeof(...);
}
or alternatively an Enum
public EGroupType GroupType
{
return EGroupType.GroupA;
}
2. supply a GroupItem Style + ControlTemplate , a gridview or datagrid with it's itemssource bound to GroupItems , from the link replace the itemscontrol with a datagrid.
3.supply a Style + ControlTemplate for the GroupBox , which contains a ScrollViewer . this is something i need further checking myself i believe that something along the lines of
<ScrollViewer>
<ContentPresenter />
</ScrollViewer>
should do the trick when supplying a GroupItem template .
4.Group .
<CollectionViewSource Source="{Binding sourceItems}" x:Key="cvs">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="GroupType"/>
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
in your window .
<GroupBox ItemsSource={StaticResource cvs} />
Upvotes: 3