So version 3.2 is compiled and ready to be released in mid-June! It has been a hectic past couple of weeks trying to get everything done and we are all very happy with the end result. I know that many of you have been anxiously waiting for the 3.2 release so I though I would give you a little preview to whet your appetite. So what exactly is included in version 3.2? Good question! It looks something like this:
- Custom distinct values (e.g., "less than 10") in the auto-filter control
- Filter row that allows end users to provide filter criteria at run time.
- Built-in support for Entity Framework
- Improvements to the datagrid's data virtualization capabilities including grouping and support for data sources implementing IQueryable (LINQ)
- Automatic detection of foreign key constraints and enumerations
- Support for unbound columns and data
- Enable and disable grouping and sorting on a per-column basis
- and a couple little extras that you will discover!
One feature that clients have often inquired about is custom distinct values. Or, in other words, being able to provide "Excel-like" filter criteria such as "less than x" and "greater than x" in the auto-filter drop down. With version 3.2, it is possible to do so and even more. How? Easy! Just use the QueryDistinctValue event exposed by each DataGridItemProperty and return the desired distinct value. For example, in the code below, I provide distinct values that will filter date/time values according to the year (by default, all dates would have been displayed in the auto-filter control) and I also provide value ranges where, by default, all values would have been displayed in the drop down.
<Grid xmlns:xcdg="http://schemas.xceed.com/wpf/xaml/datagrid">
<Grid.Resources>
<xcdg:DataGridCollectionViewSource x:Key="cvs_orders"
Source="{Binding Source={x:Static Application.Current}, Path=Orders}"
AutoFilterMode="And"
DefaultCalculateDistinctValues="False">
<xcdg:DataGridCollectionViewSource.ItemProperties>
<xcdg:DataGridItemProperty Name="OrderDate"
QueryDistinctValue="DataGridItemProperty_QueryDistinctValue_Date"
CalculateDistinctValues="True"/>
<xcdg:DataGridItemProperty Name="RequiredDate"
QueryDistinctValue="DataGridItemProperty_QueryDistinctValue_Date"
CalculateDistinctValues="True" />
<xcdg:DataGridItemProperty Name="ShippedDate"
QueryDistinctValue="DataGridItemProperty_QueryDistinctValue_Date"
CalculateDistinctValues="True" />
<xcdg:DataGridItemProperty Name="Freight"
QueryDistinctValue="DataGridItemProperty_QueryDistinctValue_Range"
CalculateDistinctValues="True" />
</xcdg:DataGridCollectionViewSource.ItemProperties>
</xcdg:DataGridCollectionViewSource>
</Grid.Resources>
<xcdg:DataGridControl x:Name="OrdersGrid"
ItemsSource="{Binding Source={StaticResource cvs_orders}}"/>
</Grid>
private void DataGridItemProperty_QueryDistinctValue_Date( object sender, QueryDistinctValueEventArgs e)
{
if( e.DataSourceValue is DateTime )
{
e.DistinctValue = ( ( DateTime )e.DataSourceValue ).ToString( "MMMM" );
}
}
private void DataGridItemProperty_QueryDistinctValue_Range(object sender,QueryDistinctValueEventArgs e)
{
if( e.DataSourceValue is decimal )
{
decimal value = ( decimal )e.DataSourceValue;
if( value <= 100 )
{
e.DistinctValue = "0 - 100";
}
else if( value > 100 && value <= 500 )
{
e.DistinctValue = "101 - 500";
}
else
{
e.DistinctValue = "500+";
}
}
}
Beautifully simple 
Version 3.2 also adds the ability for end users to provide filtering criteria at run time through the use of a "filter row", which can be added to the fixed or scrolling header and footer sections of a grid, group, or detail. In addition to supporting relation filters such as "contains", "equal to", and "greater than", among others, the filter row also supports conditional filters such as "AND" and "NOT", which allow a column to be filtered by more than one filter criterion.

Another sought-after feature is built-in support for Entity Framework. Although it was possible to use Entity Framework with the previous version of the grid, version 3.2 makes this a whole lot simpler by automatically detecting Entity collections (EntityCollection<TEntity>) and displaying their content as details. In the case where the reference to related Entity objects are not loaded, the QueryDetails event, exposed by the EntityDetailDescription class, can be handled to provide details for a data item. For example, in the code snippet below, a query that will return the appropriate details for a parent item is executed and the Handled property set to true to indicate that the event was handled.
private void EntityDetailDescription_QueryDetails( object sender, QueryEntityDetailsEventArgs e )
{
Customer customer = ( Customer )e.ParentItem;
// Since EntityFramework doesn't load automatically references to
// other objects, we build a query that will include those objects.
// We start from the base query but we could have added restrictions
// to the query.
ObjectQuery<Order> query = customer.Orders.CreateSourceQuery();
customer.Orders.Attach( query.Include( "Employee" ).Include( "Shipper" ) );
e.Handled = true;
}
A feature that was lacking in the 3.1 implementation of data virtualization was grouping support. With version 3.2, this limitation is a thing of the past :) Now, unlike the other features I just mentioned, grouping in a virtualized collection view is not something for the feint of heart! But, if you know what data you are dealing with and with the help of the Data Virtualization sample, which provides a detailed example of how to implement grouping support, you should be up and grouping in no time. If not, contact our support department, that's what they are there for 
For those of you who are already using the virtualized collection view provided with Xceed DataGrid for WPF, you may be happy to learn that version 3.2 also provides built-in support for IQueryable data sources through the DataGridVirtualizingQueryableCollectionView and its XAML-proxy the DataGridVirtualizingQueryableCollectionViewSource, which, by the way, earned its developer the "longest class name" award!
A feature that has been implemented in version 3.2 whose lack caused a lot of frustration in previous versions, is automatic detection and support for foreign keys and enumerations. In previous versions, in order to display foreign key constraints, you had to write a lot of code, which, quite honestly, was time consuming and annoying to implement. In version 3.2, all that is a thing of the past (although you can still use your code if you want!). By default, foreign key constraints defined by a DataTable or DataView used as a data source, as well as enums, can be automatically detected and displayed and edited, through a ComboBox, as the corresponding value rather than its key. If you are dealing with a different type of source or would like to provide custom key/value mappings, you can do that too. Although it is recommended to always bind the grid to its data by-proxy of a DataGridCollectionView[Source] or any other data-grid collection view, it is not obligatory. When binding a grid directly to a source that contains foreign key constraints or enums and data-grid collection view is not used, it is still possible to display the value rather than the key of the constraints and enums; however, they must be defined manually by providing the appropriate foreign key configurations, and a ForeignKeyConverter must be used in order to convert keys to values and back (see ReportsTo column in Example ).
<Grid xmlns:xcdg="http://schemas.xceed.com/wpf/xaml/datagrid">
<Grid.Resources>
<local:OccupationToStringConverter x:Key="occupationToStringConverter" />
<local:PersonForeignKeyConverter x:Key="personForeignKeyConverter" />
<ObjectDataProvider x:Key="occupationValues"
MethodName="GetValues"
ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:Occupation" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Grid.Resources>
<xcdg:DataGridControl x:Name="PersonsGrid"
ItemsSource="{Binding Source={x:Static Application.Current}, Path=Persons}">
<xcdg:DataGridControl.Columns>
<xcdg:Column FieldName="Occupation">
<xcdg:Column.CellContentTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource occupationToStringConverter}}" />
</DataTemplate>
</xcdg:Column.CellContentTemplate>
<xcdg:Column.ForeignKeyConfiguration>
<xcdg:ForeignKeyConfiguration ItemsSource="{Binding Source={StaticResource occupationValues}}"/>
</xcdg:Column.ForeignKeyConfiguration>
</xcdg:Column>
<xcdg:Column FieldName="ReportsTo">
<xcdg:Column.CellContentTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding FirstName}" />
<TextBlock Text=" " />
<TextBlock Text="{Binding LastName}" />
</StackPanel>
</DataTemplate>
</xcdg:Column.CellContentTemplate>
<xcdg:Column.ForeignKeyConfiguration>
<xcdg:ForeignKeyConfiguration ItemsSource="{Binding Source={x:Static Application.Current}, Path=Persons}"
ForeignKeyConverter="{StaticResource personForeignKeyConverter}"
ValuePath="PersonID"/>
</xcdg:Column.ForeignKeyConfiguration>
</xcdg:Column>
</xcdg:DataGridControl.Columns>
</xcdg:DataGridControl>
</Grid>
Another feature that was often requested is support for unbound columns and data. Now, you may be wondering why I am referring to unbound columns AND unbound data. Good question. Initially, this feature was known as unbound columns; however, after it was implemented, we realized that unbound columns and unbound data were two different things. Let me try to explain... "Unbound data" is data that can be "appended" to a data item through the use of unbound item properties, which are represented by the DataGridUnboundItemProperty class. Unlike "unbound columns", which can be used to display non-data related information such as a label or controls that allow some sort of action to be carried out, unbound item properties can be used to provide additional data, such as calculated columns. If you are scratching your head at this point, don't worry, it is a lot simpler than it seems! Let me demonstrate:
Unbound Data
<Grid xmlns:xcdg="http://schemas.xceed.com/wpf/xaml/datagrid">
<Grid.Resources>
<xcdg:DataGridCollectionViewSource x:Key="cvs_products"
Source="{Binding Source={x:Static Application.Current}, Path=Products}">
<xcdg:DataGridCollectionViewSource.ItemProperties>
<xcdg:DataGridUnboundItemProperty Name="TotalUnitsValue"
DataType="{x:Type sys:Double}"
QueryValue="DataGridUnboundItemProperty_QueryValue" />
</xcdg:DataGridCollectionViewSource.ItemProperties>
</xcdg:DataGridCollectionViewSource>
<local:CurrencyConverter x:Key="currencyConverter" />
</Grid.Resources>
<xcdg:DataGridControl x:Name="OrdersGrid"
ItemsSource="{Binding Source={StaticResource cvs_products}}">
<xcdg:DataGridControl.Columns>
<xcdg:Column FieldName="TotalUnitsValue"
Title="Total Inventory">
<xcdg:Column.CellContentTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource currencyConverter}}" />
</DataTemplate>
</xcdg:Column.CellContentTemplate>
</xcdg:Column>
<xcdg:Column FieldName="Photo"
Visible="False" />
</xcdg:DataGridControl.Columns>
</xcdg:DataGridControl>
</Grid>
private void DataGridUnboundItemProperty_QueryValue( object sender, DataGridItemPropertyQueryValueEventArgs e )
{
System.Data.DataRowView row = e.Item as System.Data.DataRowView;
if( row != null )
{
if( row[ "UnitsInStock" ] != DBNull.Value )
{
e.Value = ( double )( ( short )row[ "UnitsInStock" ] * ( decimal )row[ "UnitPrice" ] );
}
}
}
Unbound Columns
<Grid xmlns:xcdg="http://schemas.xceed.com/wpf/xaml/datagrid">
<Grid.Resources>
<xcdg:DataGridCollectionViewSource x:Key="cvs_products"
Source="{Binding Source={x:Static Application.Current}, Path=Products}" />
</Grid.Resources>
<xcdg:DataGridControl x:Name="OrdersGrid"
ItemsSource="{Binding Source={StaticResource cvs_products}}">
<xcdg:DataGridControl.Columns>
<xcdg:UnboundColumn FieldName="EditRowColumn"
Width="30"
MinWidth="30"
MaxWidth="30">
<xcdg:UnboundColumn.CellContentTemplate>
<DataTemplate>
<Button Click="Button_Click"
Content="..." />
</DataTemplate>
</xcdg:UnboundColumn.CellContentTemplate>
</xcdg:UnboundColumn>
<xcdg:Column FieldName="Photo"
Visible="False" />
</xcdg:DataGridControl.Columns>
</xcdg:DataGridControl>
</Grid>
private void Button_Click( object sender, RoutedEventArgs e )
{
Cell cell = Cell.FindFromChild( sender as DependencyObject );
ProductsEditorWindow editor = new ProductsEditorWindow( DataGridControl.GetParentDataGridControl( cell ).GetItemFromContainer( cell.ParentRow ) as DataRowView );
editor.ShowDialog();
}
Notice that although both the UnboundColumn and DataGridUnboundItemProperty classes both use the term "unbound" they are not meant to be used together. Meaning that an unbound item property's corresponding column is a Column and not an Unbound column.
A little feature, but one that has been often requested, is to enable and disable grouping and sorting on a per-column basis. If you are one of those who requested this feature, version 3.2 is what you need!
So there you go! Version 3.2 is scheduled to be released on June 15th. So mark the date on your calendar!
Any questions or comments? Feel free to post them in the comments section below.