I'm not sure if this is a bug or not, but here is the issue I am experiencing: I am binding a custom collection to a grid but for bands more than two levels deep, no columns will display.
I am using a System.Collections.ObjectModel.Collection(Of T) class. I am using it to store a simple class that looks like:
As you can see, the only interesting thing this class has is a reference to another collection that also contains Issues.
So say I have a form with a grid on it and then populate a collection with some Issue objects. The grid will correctly display the first and second bands, but for the third band, it will show no columns and no rows - although it looks like something should be there (you can see the indicators and spacing where the columns should be).
Here is the code that populates and binds the collection. There are three Issues in the collection: the first one has no children, the second one has one child, and the third one has one child that itself has a child.
This will display the grid but there are no rows or column headers (the columns collection is empty in the band) for the Root3/Child/Child row - although it looks like something is there since it shows the indicator and has the spacing for it.
The thing is that adding the Root3 issue as the first issue in the collection (with its child and the child's child) will work. It seems that the grid is just looking at the first item in the collection to determine 'how far down to go' for band displaying (but the databinding logic sort of works since it at least seems that it 'knows' something is really there).
Does anyone have any ideas on whether this is a bug or if there is a setting I could use to force the grid to determine how many bands to display? I've tried every setting I could think of. Binding to a DataSource or DataSet with a self-referencing table object bound to the grid at design-time and then populating it at run time works, but I would really like to associate the object in the collection with the grid and not have that intermediary (and I'm not quite sure how deep the collection will get - although realistically no more than five levels deep).
Thanks in advance for any pointers.
-David
Aach, sorry, I pasted the text from Word and when I hit the post button it changed the formatting on me, here is a better post:
Imports System.Collections.ObjectModel
Private _description As String
Public Property Description() As String
Get
End Get
Me._description = value
End Set
End Property
End Class
Dim issues As New System.Collections.ObjectModel.Collection(Of Issue)
Dim rootIssue As Issue
Dim childIssue As Issue
Dim child2Issue As Issue
'Root 1rootIssue = New Issue()
rootIssue.Description = "Root Issue #1"
issues.Add(rootIssue)
'Root 2
rootIssue = New Issue()
rootIssue.Description = "Root Issue #2"
'Root 2 Child 1
childIssue = New Issue()
childIssue.Description = "Root Issue #2/Child Issue #1"
rootIssue.ChildIssues.Add(childIssue)
'Root 3
rootIssue.Description = "Root Issue #3"
'Root 3 Child 1
childIssue.Description = "Root Issue #3/Child Issue #1"
'Root 3 Child 1 Child 1
child2Issue = New Issue()
child2Issue.Description = "Root Issue #3/Child Issue #1/Child Issue #1"
childIssue.ChildIssues.Add(child2Issue)
Me.UltraGrid1.DataSource = issues
Hi David,
dpalau said:The thing is that adding the Root3 issue as the first issue in the collection (with its child and the child's child) will work. It seems that the grid is just looking at the first item in the collection to determine 'how far down to go' for band displaying (but the databinding logic sort of works since it at least seems that it 'knows' something is really there).
That is possible. The grid cannot handle a non-homogenous data source. That means that every row of data needs to have the same depth of child data. So, for example, if the first row in the grid returns null for a property that returns the list of child rows, then no other row in the grid will have child data either. If the property returns an empty collection, then it's possible that the BindingManager will be unable to determine the structure of the data beyond that level, and the grid will base all levels of data on the first row and it's descendants.
You may be able to get around this by implementing ITypedList on your data lists and IEditableObject on your dta object. The former gives the BindingManager a way to determine the structure independent of the data. The latter allows it to create a dummy row and then cancel it in order to get the structure.
Another option to consider is using UltraWinTree instead of UltraWinGrid. The tree can handle non-homogenous data. BUt it lacks certain other features of the grid like filtering and summaries, so it may not work for the needs ofyour application.
This has nothing to do with the grid, it's an issue with the DotNet BindingManager, and I don't think it's a bug.
The BindingManager determines the data structure based on the current row of data - which is typically the first row. If your first item in the collection has no child rows, then the BindingManager cannot determine the data structure of the child rows. Implementing ITypedList allows it to determine the type of objects inthe child list.
I have tested the issue with a simple recursive class:
class Person{ public string Name { get; set; } public Collection<Person> Children { get; } }
I have filled a Collection<Person> myList with data (6 hierarchies), and bound it to the grid:
grid.DataSource = myList;It shows only 2 Bands.
grid.DataSource = new BindingList<Person>(myList);It shows only 2 Bands.
grid.DataSource = new BindingSource(myList, null);It shows all the 6 Bands.
The problem occurs only if the first row in the Band has no child.UltraWinTree has the same behaviour. It seems the DataSource property of the Infragistics controls works only with ITypedList objects.
I was having a similar issue. I was using a simple collection and binding it to the WinGrid. I wasn't using the UltraDataSource, or setting anything at desing time on the Grid. Even when the data was homogenous (accidentally loaded the same child data for each row), the datagrid would not show child rows. The space for the rows would apper along with the dashed line on the left side, but just white space for the rows.
I explored the ITypeList that Mike had suggested and added the following code to my collection definition. The grid suddenly showed the child rows. I don't actually understand what the code below does, but it worked for me.
*Update: My child rows show up now, but the first column in my grid is suddenly some huge width and it cannot be made smaller. ** Column Issue solved here: http://news.infragistics.com/forums/p/17405/63268.aspx#63268
Dim pdc As PropertyDescriptorCollection = Nothing
If listAccessors Is Nothing Then
Else
End If
End Function
For the record, I solved my problem by creating an UltraDataSource that had the structure I needed, filled it from my custom collection, and then bound that to the grid. I am able to get away with this because I know that I'm never going to have four bands deep of data and then I can just walk my collection and fill in the datasource appropriately recursively. This isn't too much of a hassle as I know the band depth and each band really only has two columns of data per band.
As I think Mike was saying, the problem is with the non-homogenous data that exists as a result of the dynamic nature of my custom collection. I tried some of the other options mentioned were either too much of a hassle (as compared to the UltraDataSource solution) or didn't work (or I didn't implement correctly).
It would be nice though if it was possible for an UltraWinGrid to check out the whole datasource to determine the band depth to go with.
Hm, that doesn't sounds like the same problem at all. Sounds like a completely different issue to me. The grid doesn't have ColumnSets, it gets the structure from the data, so I don't see how this could even be related.
The code you have posted here doesn't really help because it doesn't give any information about the grid's data source or the structure of those objects.
My best guess is that your data source is not correctly implementing IBindingList or that it contain non-homogenous data, which is not supported by the grid. But that's really just a wild guess with so little to go on.