This is my first blog at Xceed! So I will keep it simple.... promise!
This will be the first out of a series of blogs that will be posted by our support staff under the name The Tech Side. The purpose of these blogs is to demonstrate how to achieve tasks that are commonly asked by our clients.
In this post from The Tech Side, I will show how to do a few tricks in Xceed DataGrid for WPF's grouping mechanism by answering the following recurring questions:
- How do I flatten and unflatten groups?
- How can I automatically hide/unhide columns when they are grouped/ungrouped?
- How can I prevent my end users from ungrouping a certain column while still allowing grouping and ungrouping of others?
1- How do I flatten and unflatten groups?
This is the simplest of all, and is often missed by many.
You can simply set the AreGroupsFlattened property to true or false on the DataGridControl's view and, as the name implies, setting it to true would flatten the groups while setting it to false would well, unflatten them. Here is the xaml code:
<xcdg:DataGridControl Name="grid1"
ItemsSource="{Binding Source={StaticResource techSource1}}">
<xcdg:DataGridControl.View>
<xcdg:TableflowView AreGroupsFlattened="True"/>
</xcdg:DataGridControl.View>
</xcdg:DataGridControl>
And to toggle the AreGroupsFlattened from code behind, you can do the following:
TableflowView view = grid1.View as TableflowView;
view.AreGroupsFlattened = !view.AreGroupsFlattened;
2- How can I automatically hide/unhide columns when they are grouped/ungrouped?
For this one, you need to handle the CollectionChanged event of the GroupDescriptions property and change the corresponding column's Visible property. Here's an example:
grid2.ItemsSourceChangeCompleted += new EventHandler(grid2_ItemsSourceChangeCompleted);
void grid2_ItemsSourceChangeCompleted(object sender, EventArgs e)
{
DataGridCollectionView v ;
v = (DataGridCollectionView)grid2.ItemsSource;
v.GroupDescriptions.CollectionChanged += new NotifyCollectionChangedEventHandler(c_CollectionChanged);
}
void c_CollectionChanged ( object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Remove)
{
string fieldName =((DataGridGroupDescription)e.OldItems[0]). PropertyName;
grid2.Columns[fieldName ].Visible = true;
}
else
{
string fieldName =((DataGridGroupDescription)e.NewItems[0]). PropertyName;
grid2.Columns[fieldName ].Visible = false;
}
}
The reason why we handle ItemsSourceChangeCompleted first is because we are sure that after that event, the GroupDescriptions are initialized and that's where we handle the GroupDescriptions.CollectionChanged event.
3- How can I prevent my end users from ungrouping a certain column while still allowing grouping and ungrouping of others?
This one is a bit tricky, but after a few trials and errors, I was able to get it done, and in fact, the answer was pretty simple;
This can be achieved by handling the PreviewMouseMove event on GroupByItem. In the handler, I simply check if the GroupByItem is being dragged, and if its field name corresponds to the column that I want to be un-groupable. If the 2 conditions where satisfied I simply set e.Handled = true on the event and that disables un-grouping of that column! Here's an example:
<Style TargetType="{x:Type xcdg:GroupByItem}">
<Style.Setters>
<EventSetter Event="PreviewMouseMove" Handler="g_PreviewMouseMove"/>
</Style.Setters>
</Style>
void g_PreviewMouseMove(object sender, MouseEventArgs e)
{
GroupLevelDescription gld = (GroupLevelDescription)(sender as GroupByItem).Content;
if ((sender as GroupByItem).IsBeingDragged && gld.FieldName == "Name")
e.Handled = true;
}
You can download the source code for the previous examples here, and don't forget to leave your comments and suggestions for future blog posts in the comments section below!
Michel