There's a weird bug I found in the Infragistics export class. It has to do with exporting a grid that has a custom header. It has a work-around, but it's ugly. Let's start off by seeing a limitation of the exporter, the Infragistics work-around, and a working work-around.
The Exporter throws an exception if you have a custom header.
Create a new VB WPF Framework project in Visual Studio 2019 and call it ExportCustomHeader. Add these references.
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:igDP="http://infragistics.com/DataPresenter"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<RoutedCommand x:Key="Export"/>
</Window.Resources>
<Window.CommandBindings>
<CommandBinding Command="{StaticResource Export}" Executed="CommandBinding_Executed"/>
</Window.CommandBindings>
<StackPanel Orientation="Vertical">
<Button Content="Export" Command="{StaticResource Export}" Width="200"/>
<igDP:XamDataGrid DataSource="{Binding Items}" Loaded="XamDataGrid_Loaded">
<igDP:XamDataGrid.FieldSettings>
<igDP:FieldSettings AllowSummaries="False" SummaryUIType="SingleSelect" LabelTextAlignment="Center"/>
</igDP:XamDataGrid.FieldSettings>
<igDP:XamDataGrid.FieldLayoutSettings>
<igDP:FieldLayoutSettings AutoGenerateFields="False"/>
</igDP:XamDataGrid.FieldLayoutSettings>
<igDP:XamDataGrid.FieldLayouts>
<igDP:FieldLayout>
<igDP:FieldLayout.Fields>
<igDP:CheckBoxField Name="IsSelected">
<igDP:CheckBoxField.Label>
<StackPanel Orientation="Horizontal">
<CheckBox/>
<TextBlock Text="Selected"/>
</StackPanel>
</igDP:CheckBoxField.Label>
</igDP:CheckBoxField>
<igDP:TextField Label="Description" Name="Description"/>
</igDP:FieldLayout.Fields>
</igDP:FieldLayout>
</igDP:XamDataGrid.FieldLayouts>
</igDP:XamDataGrid>
</StackPanel>
</Window>
Class MainWindow
Implements INotifyPropertyChanged
Private xdg As XamDataGrid
Public Class cItem
Public Property IsSelected As Boolean
Public Property Description As String
End Class
Private _Items As Collections.Generic.List(Of cItem)
Public ReadOnly Property Label As String = "HI MOM"
Public Sub New()
Items = New List(Of cItem)() From {
End Sub
Public Property Items As Collections.Generic.List(Of cItem)
Return _Items
Set(value As Collections.Generic.List(Of cItem))
End Set
End Property
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Public Function SetProperty(Of T)(ByRef storage As T, value As T, <System.Runtime.CompilerServices.CallerMemberName> Optional PropertyName As String = Nothing) As Boolean
If Object.Equals(storage, value) Then Return False
storage = value
NotifyPropertyChanged(PropertyName)
Return True
End Function
Private Sub CommandBinding_Executed(sender As Object, e As ExecutedRoutedEventArgs)
excelExporter.Export(xdg, FilePath, Infragistics.Documents.Excel.WorkbookFormat.Excel2007)
Process.Start(FilePath)
Private Sub XamDataGrid_Loaded(sender As Object, e As RoutedEventArgs)
End Class
Modify CommandBinding_Executed to specify an event handler.
e.Label = "SELECTED"
End If
End Sub
I contacted Infragistics support (they're better than average) and got a response in 24 hours. Without admitting this is a bug, they provided a work-around that involves styling the label presenter to override the template. I tweaked their solution a bit because eventually I needed to do this in code. Change the XAML to look like this.
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:igDP="http://infragistics.com/DataPresenter"
xmlns:local="clr-namespace:BindXamToDataSet"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="MainWindow2" Height="450" Width="800">
<Window.Resources>
<RoutedCommand x:Key="Export"/>
</Window.Resources>
<Window.CommandBindings>
<CommandBinding Command="{StaticResource Export}" Executed="CommandBinding_Executed"/>
</Window.CommandBindings>
<StackPanel Orientation="Vertical">
<Button Content="Export" Command="{StaticResource Export}" Width="200"/>
<igDP:XamDataGrid DataSource="{Binding Items}" Loaded="XamDataGrid_Loaded">
<igDP:XamDataGrid.FieldSettings>
<igDP:FieldSettings AllowSummaries="False" SummaryUIType="SingleSelect" LabelTextAlignment="Center" AllowEdit="False"/>
</igDP:XamDataGrid.FieldSettings>
<igDP:XamDataGrid.FieldLayoutSettings>
<igDP:FieldLayoutSettings AutoGenerateFields="False"/>
</igDP:XamDataGrid.FieldLayoutSettings>
<igDP:XamDataGrid.FieldLayouts>
<igDP:FieldLayout>
<igDP:FieldLayout.Fields>
<igDP:CheckBoxField Name="IsSelected">
<igDP:CheckBoxField.Settings>
<igDP:FieldSettings>
<igDP:FieldSettings.LabelPresenterStyle>
<Style TargetType="igDP:LabelPresenter">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox/>
<TextBlock Text="Selected"/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</igDP:FieldSettings.LabelPresenterStyle>
</igDP:FieldSettings>
</igDP:CheckBoxField.Settings>
</igDP:CheckBoxField>
<igDP:TextField Label="Description" Name="Description"/>
</igDP:FieldLayout.Fields>
</igDP:FieldLayout>
</igDP:XamDataGrid.FieldLayouts>
</igDP:XamDataGrid>
</StackPanel>
</Window>
You can see their solution is far more complicated and is functionally equivalent to the original XAML but for some reason the Exporter is OK with it