Creating a Custom Detail Description
The following example demonstrates how to create and use a custom detail description that handles LINQ detail relations, which are provided by properties to which the AssociationAttribute is applied.
- XAML
- C#
- VB.NET
<Grid>
<Grid.Resources>
<xcdg:DataGridCollectionViewSource x:Key="cvs_employees"
Source="{Binding Source={x:Static Application.Current},
Path=LinqDataContext.Employees}">
<xcdg:DataGridCollectionViewSource.DetailDescriptions>
<local:LinqToSqlDetailDescription RelationName="Employee_Employees"
Title="Employees" />
<local:LinqToSqlDetailDescription RelationName="Employee_Customer"
Title="Customers">
<local:LinqToSqlDetailDescription.DetailDescriptions>
<local:LinqToSqlDetailDescription RelationName="Customer_Order"
Title="Orders">
<local:LinqToSqlDetailDescription.DetailDescriptions>
<local:LinqToSqlDetailDescription RelationName="Order_Order_Detail"
Title="Order Details" />
</local:LinqToSqlDetailDescription.DetailDescriptions>
</local:LinqToSqlDetailDescription>
</local:LinqToSqlDetailDescription.DetailDescriptions>
</local:LinqToSqlDetailDescription>
</xcdg:DataGridCollectionViewSource.DetailDescriptions>
</xcdg:DataGridCollectionViewSource>
</Grid.Resources>
<xcdg:DataGridControl x:Name="EmployeesGrid"
ItemsSource="{Binding Source={StaticResource cvs_employees}}"
ItemsSourceName="Employee Information"
AutoCreateDetailConfigurations="True" />
</Grid>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xceed.Wpf.DataGrid;
using System.Reflection;
using System.Data.Linq.Mapping;
using System.Diagnostics;
using System.Collections;
namespace Xceed.Wpf.Documentation
{
public class LinqToSqlDetailDescription: DataGridDetailDescription
{
protected override IEnumerable GetDetailsForParentItem( DataGridCollectionView parentCollectionView,
object parentItem )
{
Type parentItemType = parentItem.GetType();
PropertyInfo foundProperty = null;
PropertyInfo[] properties = parentItemType.GetProperties();
foreach( PropertyInfo propertyInfo in properties )
{
object[] attributes = propertyInfo.GetCustomAttributes( typeof( AssociationAttribute ), false );
if( attributes.GetLength( 0 ) == 0 )
continue;
AssociationAttribute associationAttribute = ( AssociationAttribute )attributes[ 0 ];
if( associationAttribute.Name == this.RelationName )
{
foundProperty = propertyInfo;
break;
}
}
if( foundProperty == null )
{
return new object[] { };
}
else
{
object details = foundProperty.GetValue( parentItem, null );
Type detailsType = details.GetType();
MethodInfo getNewBindingList = detailsType.GetMethod( "GetNewBindingList" );
return ( IEnumerable )getNewBindingList.Invoke( details, null );
}
}
}
}
/*---*/
NorthwindDataContext context = new NorthwindDataContext();
DataGridCollectionView collectionView = new DataGridCollectionView( context.Employees, typeof( Employee ), true, false );
collectionView.DetailDescriptions.Add( new LinqToSqlDetailDescription( "Employee_Employees", "Employees" ) );
LinqToSqlDetailDescription employeeCustomerDetail = new LinqToSqlDetailDescription( "Employee_Customer", "Customers" );
LinqToSqlDetailDescription customerOrderDetail = new LinqToSqlDetailDescription( "Customer_Order", "Orders" );
customerOrderDetail.DetailDescriptions.Add( new LinqToSqlDetailDescription( "Order_Order_Detail", "Order Details" ) );
employeeCustomerDetail.DetailDescriptions.Add( customerOrderDetail );
collectionView.DetailDescriptions.Add( employeeCustomerDetail );
dataGridControl.AutoCreateDetailConfigurations = true;
dataGridControl.ItemsSourceName = "Employee Information";
dataGridControl.ItemsSource = collectionView;
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports Xceed.Wpf.DataGrid
Imports System.Reflection
Imports System.Data.Linq.Mapping
Imports System.Diagnostics
Imports System.Collections
Namespace Xceed.Wpf.Documentation
Public Class LinqToSqlDetailDescription
Inherits DataGridDetailDescription
Protected Overrides Function GetDetailsForParentItem( ByVal parentCollectionView As DataGridCollectionView, _
ByVal parentItem As Object ) As IEnumerable
Dim parentItemType As Type = parentItem.GetType()
Dim foundProperty As PropertyInfo = Nothing
Dim properties() As PropertyInfo = parentItemType.GetProperties()
Dim propertyInfo As PropertyInfo
For Each propertyInfo In properties
Dim attributes() As Object = propertyInfo.GetCustomAttributes( Type.GetType( AssociationAttribute ), _
False)
If attributes.GetLength( 0 ) = 0 Then
continue
End If
Dim associationAttribute As AssociationAttribute = CType( attributes( 0 ), AssociationAttribute )
If associationAttribute.Name = Me.RelationName Then
foundProperty = propertyInfo
Exit Property
End If
Next
If foundProperty Is Nothing Then
Return New Object()
Else
Dim details As Object = foundProperty.GetValue( parentItem, Nothing )
Dim detailsType As Type = details.GetType()
Dim getNewBindingList As MethodInfo = detailsType.GetMethod( "GetNewBindingList" )
Return CType( getNewBindingList.Invoke( details, Nothing), IEnumerable )
End If
End Function
End Class
End Namespace
'-----
Dim context As New NorthwindDataContext()
Dim collectionView As New DataGridCollectionView( context.Employees, GetType( Employee ), True, False )
collectionView.DetailDescriptions.Add( New LinqToSqlDetailDescription( "Employee_Employees", "Employees" ) )
Dim employeeCustomerDetail As New LinqToSqlDetailDescription( "Employee_Customer", "Customers" )
Dim customerOrderDetail As New LinqToSqlDetailDescription( "Customer_Order", "Orders" )
customerOrderDetail.DetailDescriptions.Add( New LinqToSqlDetailDescription( "Order_Order_Detail", "Order Details" ) )
employeeCustomerDetail.DetailDescriptions.Add( customerOrderDetail )
collectionView.DetailDescriptions.Add( employeeCustomerDetail )
dataGridControl.AutoCreateDetailConfigurations = True
dataGridControl.ItemsSourceName = "Employee Information"
dataGridControl.ItemsSource = collectionView