I came across yet another Infragistics XamDataGrid bug the other day. I sent it to Infragistcs support, which is normally very good, but the guy working on this is having trouble understanding why this is a problem.
The bug concerns a parent layout that has two child layouts. It displays expanders and labels when it should not. Here's a sample XAML and code.
<Window x:Class="MainWindow"
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:local="clr-namespace:WpfApp9"
xmlns:igDP="http://infragistics.com/DataPresenter"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="MainWindow" Height="450" Width="800">
<Grid>
<igDP:XamDataGrid DataSource="{Binding Parents}">
<igDP:XamDataGrid.FieldSettings>
<igDP:FieldSettings AllowEdit="False"/>
</igDP:XamDataGrid.FieldSettings>
<igDP:XamDataGrid.FieldLayoutSettings>
<igDP:FieldLayoutSettings AutoGenerateFields="False" ExpansionIndicatorDisplayMode="CheckOnDisplay"/>
</igDP:XamDataGrid.FieldLayoutSettings>
<igDP:XamDataGrid.FieldLayouts>
<igDP:FieldLayout Key="Parents">
<igDP:FieldLayout.Fields>
<igDP:TextField Label="Parent
Name" Name="ParentName"/>
<igDP:Field Name="Children1"/>
<igDP:Field Name="Children2"/>
</igDP:FieldLayout.Fields>
</igDP:FieldLayout>
<igDP:FieldLayout ParentFieldLayoutKey="Parents" ParentFieldName="Children1" Key="Children1">
<igDP:FieldLayout.Settings>
<igDP:FieldLayoutSettings LabelLocation="Hidden"/>
</igDP:FieldLayout.Settings>
<igDP:FieldLayout.Fields>
<igDP:TextField Label="Name" Name="ChildName"/>
</igDP:FieldLayout.Fields>
</igDP:FieldLayout>
<igDP:FieldLayout ParentFieldLayoutKey="Parents" ParentFieldName="Children2" Key="Children2">
<igDP:FieldLayout.Settings>
<igDP:FieldLayoutSettings LabelLocation="Hidden"/>
</igDP:FieldLayout.Settings>
<igDP:FieldLayout.Fields>
<igDP:TextField Label="Name" Name="ChildName"/>
</igDP:FieldLayout.Fields>
</igDP:FieldLayout>
</igDP:XamDataGrid.FieldLayouts>
</igDP:XamDataGrid>
</Grid>
</Window>
----------------------------------------------
Class MainWindow
Public Class cParent
Public Property ParentName As String
Public Property Children1 As List(Of cChild)
Public Property Children2 As List(Of cChild)
End Class
Public Class cChild
Public Property ChildName As String
End Class
Public Property Parents As New List(Of cParent) From
{
New cParent() With {.ParentName = "Parent1",
.Children1 = New List(Of cChild) From {New cChild() With {.ChildName = "Parent1.Child1"}},
.Children2 = New List(Of cChild) From {New cChild() With {.ChildName = "Parent1.Child2"}}},
New cParent() With {.ParentName = "Parent2",
.Children1 = Nothing,
.Children2 = Nothing}
}
End Class
As you can see, I have hidden the labels on the child rows and expansion indicators are visible only on parents that have children. Parent1 has children and Parent2 does not.
The result looks like this.
I am not expecting Parent2 to have an expander button and I am not expecting the "Children1" and "Childrent2" labels because their location is set to hidden. I'm expecting it to look a bit like this when parent1 is expanded.
If I remove either of the child bands the grid behaves the way I expect.
<Window x:Class="MainWindow"
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:local="clr-namespace:WpfApp9"
xmlns:igDP="http://infragistics.com/DataPresenter"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="MainWindow" Height="450" Width="800">
<Grid>
<igDP:XamDataGrid DataSource="{Binding Parents}">
<igDP:XamDataGrid.FieldSettings>
<igDP:FieldSettings AllowEdit="False"/>
</igDP:XamDataGrid.FieldSettings>
<igDP:XamDataGrid.FieldLayoutSettings>
<igDP:FieldLayoutSettings AutoGenerateFields="False" ExpansionIndicatorDisplayMode="CheckOnDisplay"/>
</igDP:XamDataGrid.FieldLayoutSettings>
<igDP:XamDataGrid.FieldLayouts>
<igDP:FieldLayout Key="Parents">
<igDP:FieldLayout.Fields>
<igDP:TextField Label="Parent Name" Name="ParentName"/>
<igDP:Field Name="Children1"/>
<!--<igDP:Field
Name="Children2"/>-->
</igDP:FieldLayout.Fields>
</igDP:FieldLayout>
<igDP:FieldLayout ParentFieldLayoutKey="Parents" ParentFieldName="Children1" Key="Children1">
<igDP:FieldLayout.Settings>
<igDP:FieldLayoutSettings LabelLocation="Hidden"/>
</igDP:FieldLayout.Settings>
<igDP:FieldLayout.Fields>
<igDP:TextField Label="Name" Name="ChildName"/>
</igDP:FieldLayout.Fields>
</igDP:FieldLayout>
<!--<igDP:FieldLayout
ParentFieldLayoutKey="Parents" ParentFieldName="Children2"
Key="Children2">
<igDP:FieldLayout.Settings>
<igDP:FieldLayoutSettings LabelLocation="Hidden"/>
</igDP:FieldLayout.Settings>
<igDP:FieldLayout.Fields>
<igDP:TextField
Label="Name" Name="ChildName"/>
</igDP:FieldLayout.Fields>
</igDP:FieldLayout>-->
</igDP:XamDataGrid.FieldLayouts>
</igDP:XamDataGrid>
</Grid>
</Window>
Now Parent2 does not have an expander and the labels are not displayed.
Update: So Infragistics explained that the blue tags are not labels but expanders. When you have a single child band you don't see them and when you expand the parent you immediately see just the children as in the image above. When there are multiple child bands you see the expanders first and you use them to decide which child band to expand.
OK, this makes sense. Except that there's no way to override this behavior. Also, I would expect the XamDataGrid to realize that a collection of empty collections contains no data, so Parent2 doesn't need an expander.
Here's the response from Infragistics support..
Unfortunately there is no way you can remove expandable field records( expander labels) with XamDatagrid and that is why we build another control called XamTreeGrid.
Seriously? You built another control just because you couldn't fix this? I could have saved you a lot of time. You have to collapse the expander record in the RecordInitialized event then take responsibility for expanding and collapsing its children yourself.
Using the project above, add some event handlers to the XamDataGrid and then write them.
<igDP:XamDataGrid DataSource="{Binding Parents}"
InitializeRecord="XamDataGrid_InitializeRecord"
RecordExpanded="XamDataGrid_RecordExpanded"
RecordCollapsed="XamDataGrid_RecordCollapsed">
----------------------------------------------------
Private Sub XamDataGrid_InitializeRecord(sender As Object, e As Events.InitializeRecordEventArgs)
Dim er As ExpandableFieldRecord = TryCast(e.Record, ExpandableFieldRecord)
Dim dr As DataRecord
Dim dataItem As cParent
Dim diType As Type
Dim PI As PropertyInfo
Dim collection As IList
If er IsNot Nothing Then
er.ExpansionIndicatorVisibility = Visibility.Collapsed
dr = DirectCast(er.ParentRecord, DataRecord)
dataItem = TryCast(dr.DataItem, cParent)
diType = dataItem.GetType()
PI =
diType.GetProperty(er.Field.Name)
collection = TryCast(PI.GetValue(dataItem), IList)
If collection Is Nothing OrElse collection.Count = 0 Then
er.Visibility = Visibility.Collapsed
End If
End If
End Sub
Private Sub XamDataGrid_RecordExpanded(sender As Object, e As Events.RecordExpandedEventArgs)
SyncExpandableRecords(TryCast(e.Record, DataRecord))
End Sub
Private Sub XamDataGrid_RecordCollapsed(sender As Object, e As Events.RecordCollapsedEventArgs)
SyncExpandableRecords(TryCast(e.Record, DataRecord))
End Sub
Private Sub SyncExpandableRecords(dr As DataRecord)
dr?.ChildRecords.OfType(Of ExpandableFieldRecord).ToList().ForEach(Sub(er) er.IsExpanded =
dr.IsExpanded)
End Sub
The XamDataGrid_InitializeRecord event handler collapses the expansion indicator for all Expandable records. If the IList it is expanding is empty the entire expandable record is collapsed. Note cParent could be replaced with Object to be more generic.
When we collapse the expander record, it will no longer be able to expand/collapse its children so we have to take responsibility for that ourselves when the parent record is expanded or collapsed.
I have not tested this with more complex hierarchies or when binding to datasets. But clearly, it can be done.
|
Ta Da! |