Xceed Toolkit Plus for WPF v4.6 Documentation
Custom KeyValue Mappings

The following example demonstrates how to bind the grid directly to a BindingList<Person> objects and provide a custom key/value mapping through a ForeignKeyConverter, which will return the appropriate employee first and last names for the provided employee ID.

XAML
Copy Code
<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>

The following code provides the implementation of the PersonForeignKeyConverter class. 

VB.NET
Copy Code
Public Class PersonForeignKeyConverter
             Inherits ForeignKeyConverter
  Public Overrides Function GetKeyFromValue( value As Object, configuration As ForeignKeyConfiguration ) As Object
    Dim bindingList As PersonBindingList = TryCast( configuration.ItemsSource, PersonBindingList )
    If Not bindingList Is Nothing Then
      Dim person As Person = TryCast( value, Person )
      If Not person Is Nothing Then
        Return person.PersonID
      End If
    End If
    Return -1
  End Function
  Public Overrides Function GetValueFromKey( key As Object, configuration As ForeignKeyConfiguration ) As Object
   Dim bindingList As PersonBindingList = TryCast( configuration.ItemsSource, PersonBindingList )
    If Not bindingList Is Nothing Then
      Try
        Dim personID As Integer = CInt( key )
        Dim person As Person
        For Each person In bindingList
          If person.PersonID = personID Then
            Return person
          End If
        Next person
      Catch e As Exception
        ' key can be nothing
      End Try
    Return Nothing
  End Function
End Class
C#
Copy Code
public class PersonForeignKeyConverter : ForeignKeyConverter
{
 public override object GetKeyFromValue( object value, ForeignKeyConfiguration configuration )
 {
   PersonBindingList bindingList = configuration.ItemsSource as PersonBindingList;
   if( bindingList != null )
   {
     Person person = value as Person;
     if( person != null )
     {
       return person.PersonID;
     }
   }
   return -1;
 }
 public override object GetValueFromKey( object key, ForeignKeyConfiguration configuration )
 {
   PersonBindingList bindingList = configuration.ItemsSource as PersonBindingList;
   if( bindingList != null )
   {
     try
     {
       int personID = ( int )key;
       foreach( Person person in bindingList )
       {
         if( person.PersonID == personID )
         {
           return person;
         }
       }
     }
     catch( Exception )
     {
       // key can be null
     }
   }
   return null;
 }
}

The following code provides the implementation of the OccupationToStringConverter class.

VB.NET
Copy Code
public class OccupationToStringConverter: IValueConverter
{
  Public Function Convert( value As Object, targetType As Type, parameter As Object,
                           culture As System.Globalization.CultureInfo ) As Object Implements IValueConverter.Convert
    If( Not value Is Nothing ) AndAlso ( TypeOf value Is Occupation ) Then
      Dim enumString As String = value.ToString()
      ' Start at 1 to ignore the first capitalizes letter.
      Dim i as Integer = 1
      For i To i < enumString.Length - 1
        If char.IsUpper( enumString( i ) ) Then
          enumString = enumString.Insert( i, " " )
          i++
        End If
      Next i
      Return enumString
    End If
    Return Nothing
  End Function
  Public Function ConvertBack( value As Value, targetType As Type, parameter As Object,
                               culture As System.Globalization.CultureInfo ) As Object Implements IValueConverter.ConvertBack
    Return Binding.DoNothing
  End Function
End Class
C#
Copy Code
public class OccupationToStringConverter: IValueConverter
{
 public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
 {
   if( value != null && value is Occupation)
   {
     string enumString = value.ToString();
     // Start at 1 to ignore the first capitalizes letter.
     for( int i = 1; i < enumString.Length - 1; i++ )
     {
       if( char.IsUpper( enumString[ i ] ) )
       {
         enumString = enumString.Insert( i, " " );
         i++;
       }
     }
     return enumString;
   }
   return null;
 }
 public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
 {
   return Binding.DoNothing;
 }
}