View previous topic :: View next topic |
Author |
Message |
EntityDev
Joined: 07 Apr 2016 Posts: 40
|
Posted: Wed Apr 13, 2016 7:51 pm Post subject: Cannot get sorting to work |
|
|
Hello,
I developed a collection class inheriting from ArrayList, implementing:
IList
ICollection
IEnumerable
ICloneable
IBindingList
ITypedList
I cannot get the VirtualTree to sort on a loaded collection. All columns are set to allow sorting. I plopped a DataGridView onto the same form to verify I wasn't going nuts, retrieved some objects and ran it - and it sorts the collection.
Oddly, after sorting on a column in the DataGridView, I can then sort a column in the VirtualTree - but just once. Subsequent clicks do nothing. If I sort a column in the DataGridView again, I can then sort, once, in VirtualTree.
This I can rinse and repeat all day - which may or may not help you to understand what's going on - maybe not. But is there a simple property setting on VirtualTree I'm overlooking, which enables/disables sorting? I only find property Sortable on Column. |
|
Back to top |
|
|
EntityDev
Joined: 07 Apr 2016 Posts: 40
|
Posted: Wed Apr 13, 2016 7:57 pm Post subject: |
|
|
Interesting..I just spotted this: SortableBindingList problems
And it appears to be the same cause. I'll try the solution described there. |
|
Back to top |
|
|
EntityDev
Joined: 07 Apr 2016 Posts: 40
|
Posted: Wed Apr 13, 2016 8:25 pm Post subject: |
|
|
I tried the steps in that thread. Unfortunately I am still unable to sort. The addition of the row binding for the collection class didn't make the tree behave any differently.
It will still sort one time only if I prod the DGV. Strange...
I also removed the DataGridView and rebuilt - no bueno. |
|
Back to top |
|
|
Infralution
Joined: 28 Feb 2005 Posts: 5027
|
Posted: Wed Apr 13, 2016 10:58 pm Post subject: |
|
|
Quote: | Oddly, after sorting on a column in the DataGridView, I can then sort a column in the VirtualTree - but just once. Subsequent clicks do nothing. If I sort a column in the DataGridView again, I can then sort, once, in VirtualTree. |
That is a bit strange. Have you implemented the ITypeList interface yourself or is it implemented by the Entity Framework?
For sorting to work in Virtual Tree you must define a binding for the root row. So it is probably a good idea to have Show Root Row turned on and confirm that the binding you have defined for the root row is working (by checking that text displayed is formatted using the Format property text you have defined for the CellBinding).
Another thing you could try is using the standard SortableBindingList that we supply (defined in Infralution.Common) - add some of your items to this collection and set it as your root row (with a binding to it). This will tell you whether the problem is with your implementation of ITypedList - or some other issue. _________________ Infralution Support |
|
Back to top |
|
|
EntityDev
Joined: 07 Apr 2016 Posts: 40
|
Posted: Thu Apr 14, 2016 6:41 am Post subject: |
|
|
Indeed, and it's gotten a bit stranger...
I implemented it myself, using what I've learned by studying the many generic SortableBindingList type implementations out there which implement IBindingList(Of T). I've also tried another I developed which derives from ArrayList and implements IBindingList and ITypedList. At any rate, I've tried several of the aforementioned implementations, and now I've tried yours as well.
I studied the matter a bit closer this time. I should say that the behavior with your SortableBindingList is the same as I described earlier. At least, I think so. As I say, I've looked closer and can describe the behavior in more detail.
Please note that I tested this with EF classes and with some simple classes. The behavior is precisely the same.
And that behavior is that I can only sort in the DataGridView, and only on a DateTime column. The list in the VirtualTree follows suit. In other words, when I sort on a Date column (only) in the DataGridView, the VirtualTree also sorts. I cannot sort on any column type in the VirtualTree itself. This behavior was noted during a test with the simple classes, as follows:
Code: | Public Class Master
Public Property MasterName As String
Public Property DateCreated As DateTime
Public Overridable Property Details As New List(Of Detail)
End Class
Public Class Detail
Public Property DetailName
Public Property DateCreated As DateTime
End Class |
I loaded the VirtualTree and DataGridView with several types of collection classes:
Code: | Private Sub LoadData()
Using New WaitCursor
Dim m1 As New Master With {.MasterName = "Master 01", .DateCreated = "01/01/01"}
m1.Details.Add(New Detail With {.DetailName = "Detail 01", .DateCreated = "01/01/01"})
m1.Details.Add(New Detail With {.DetailName = "Detail 02", .DateCreated = "01/01/01"})
m1.Details.Add(New Detail With {.DetailName = "Detail 03", .DateCreated = "01/01/01"})
m1.Details.Add(New Detail With {.DetailName = "Detail 04", .DateCreated = "01/01/01"})
m1.Details.Add(New Detail With {.DetailName = "Detail 05", .DateCreated = "01/01/01"})
Dim m2 As New Master With {.MasterName = "Master 02", .DateCreated = "01/01/01"}
m2.Details.Add(New Detail With {.DetailName = "Detail 01", .DateCreated = "01/01/01"})
m2.Details.Add(New Detail With {.DetailName = "Detail 02", .DateCreated = "01/01/01"})
m2.Details.Add(New Detail With {.DetailName = "Detail 03", .DateCreated = "01/01/01"})
m2.Details.Add(New Detail With {.DetailName = "Detail 04", .DateCreated = "01/01/01"})
m2.Details.Add(New Detail With {.DetailName = "Detail 05", .DateCreated = "01/01/01"})
Dim m3 As New Master With {.MasterName = "Master 03", .DateCreated = "01/01/01"}
m3.Details.Add(New Detail With {.DetailName = "Detail 01", .DateCreated = "01/01/01"})
m3.Details.Add(New Detail With {.DetailName = "Detail 02", .DateCreated = "01/01/01"})
m3.Details.Add(New Detail With {.DetailName = "Detail 03", .DateCreated = "01/01/01"})
m3.Details.Add(New Detail With {.DetailName = "Detail 04", .DateCreated = "01/01/01"})
m3.Details.Add(New Detail With {.DetailName = "Detail 05", .DateCreated = "01/01/01"})
Dim bl As New Infralution.Common.SortableBindingList(Of Master)
Dim ol As New ObservableListSource(Of Master)
Dim oc As New ObservableCollection(Of Master)
Dim al As New ArrayList
Dim sl As New SortableBindingList(Of Master)
bl.Add(m1)
bl.Add(m2)
bl.Add(m3)
ol.Add(m1)
ol.Add(m2)
ol.Add(m3)
oc.Add(m1)
oc.Add(m2)
oc.Add(m3)
al.Add(m1)
al.Add(m2)
al.Add(m3)
sl.Add(m1)
sl.Add(m2)
sl.Add(m3)
Me.JobsVirtualTree.DataSource = bl
Me.DataGridView1.DataSource = bl
For Each i In bl.GetType.GetInterfaces
Debug.Print(i.Name)
Next
End Using
End Sub |
This is in a VS2010 Pro Winforms project .Net Framework 4, Windows 7 Professional, Target CPU is x86. My SortableBindingList behaves just like yours, so I didn't post the code for it. The VirtualTree is configured with manually added ObjectRowBindings. The DataGridView generated its columns and I removed the Master.Details column. I'm only binding the Master row in VirtualTree.
Best Regards |
|
Back to top |
|
|
Infralution
Joined: 28 Feb 2005 Posts: 5027
|
Posted: Thu Apr 14, 2016 7:47 am Post subject: |
|
|
If you can encapsulate this in a sample project without dependencies then that would be the quickest way to resolve this I think. Sorting and the ITypedList interface can get rather complicated. You can email a zipped copy of the project to support@infralution.com
There are other ways to achieve sorting - but using the ITypeList interface is nice because once you have it working you don't have to implement any other plumbing. _________________ Infralution Support |
|
Back to top |
|
|
EntityDev
Joined: 07 Apr 2016 Posts: 40
|
Posted: Thu Apr 14, 2016 12:13 pm Post subject: |
|
|
Agreed, I like things that are already plumbed. I'll build a small project and send it. Thank you once again. |
|
Back to top |
|
|
EntityDev
Joined: 07 Apr 2016 Posts: 40
|
Posted: Thu Apr 14, 2016 2:35 pm Post subject: |
|
|
I have emailed support with a sample project. The only dependencies to deal with are Infralution's. You might have those .dlls lying about. |
|
Back to top |
|
|
EntityDev
Joined: 07 Apr 2016 Posts: 40
|
Posted: Thu Apr 14, 2016 3:22 pm Post subject: |
|
|
A possible Eureka moment here. From another thread:
Quote: | The ChildProperty for the root binding should be set to "this"
Secondly for the RowBinding you create for items in the list you should set the TypeListName property (not the TypeName or Type property). This should be set to the Name returned by ITypedList.GetListName(null). This means that Virtual Tree will use the ITypedList interface to retrieve information about the items (rather than using reflection). |
Sorting work now for all columns in VirtualTree, at least when using the simple classes. I didn't have to use fully qualified names, nor assembly names, just the name of the object in the TypeListName property. The explanation quoted above makes me realize that I could have inferred the intent of the TypedListName property.
I'll test a bit later with DbContext classes. |
|
Back to top |
|
|
EntityDev
Joined: 07 Apr 2016 Posts: 40
|
Posted: Thu Apr 14, 2016 4:17 pm Post subject: |
|
|
Nah! I had it, then I played around and messed it up.
I have sorting working on all columns except the Main. I had Main working at first, but somehow lost it. |
|
Back to top |
|
|
EntityDev
Joined: 07 Apr 2016 Posts: 40
|
Posted: Thu Apr 14, 2016 4:58 pm Post subject: |
|
|
After some close study, I find that using the TypedListName property as opposed to reflected types has an undesirable side effect. I cannot get child rows to populate their bound columns with data.
When using reflected types (TypeName), I get property data for children but of course no sorting.
And I still can't get the "main" column to sort. I could swear that it was working. Even so, I didn't have child row data... |
|
Back to top |
|
|
Infralution
Joined: 28 Feb 2005 Posts: 5027
|
Posted: Thu Apr 14, 2016 9:53 pm Post subject: |
|
|
I've received your sample project and will check out what the issue is. _________________ Infralution Support |
|
Back to top |
|
|
EntityDev
Joined: 07 Apr 2016 Posts: 40
|
Posted: Thu Apr 14, 2016 9:59 pm Post subject: |
|
|
I've got all this working now. Thank you for your guidance and your patience.
For anyone following this who wishes to avoid my missteps, feel free to reply and I'll write up the steps that worked for me. Please keep in mind that this is an Object data binding scenario. Binding to DataSets is a much different thing. |
|
Back to top |
|
|
|