Infralution Support Forum Index Infralution Support
Support groups for Infralution products
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

ObjectRowBinding as child of a row

 
Post new topic   Reply to topic    Infralution Support Forum Index -> Virtual Tree Support
View previous topic :: View next topic  
Author Message
EntityDev



Joined: 07 Apr 2016
Posts: 40

PostPosted: Sun Apr 17, 2016 7:58 pm    Post subject: ObjectRowBinding as child of a row Reply with quote

This sort of question is asked in various ways in the forum. I have searched, but didn't find an answer that quite fits my scenaro. My current effort is to do a mix of Object and Programmatic databinding. My question - is it possible to display data like this:

Root Row (IList) (ObjectRowBinding)
----Object 1
--------ObjectCollection 1 (IList) (ObjectRowBinding)
------------Object 1
------------Object 2
--------ObjectCollection 2 (IList) (ObjectRowBinding)
------------Object 1
------------Object 2
----Object 2
--------ObjectCollection 1 (IList) (ObjectRowBinding)
------------Object 1
------------Object 2
--------ObjectCollection 2 (IList) (ObjectRowBinding)
------------Object 1
------------Object 2

In my reading archived threads, it seems this can be done, but the subject has usually involved DataSets and has been different in scope. If this is possible, please tell me which events to handle (VirtualTree, Row, Binding or otherwise) and which Types to use. I code in VB.Net.

Thank you.
Back to top
View user's profile Send private message
Infralution



Joined: 28 Feb 2005
Posts: 4999

PostPosted: Mon Apr 18, 2016 1:24 am    Post subject: Reply with quote

You can display any hierarchical data structure in Virtual Tree. However if your underlying data is in a different form then you will need to create a data model that Virtual Tree can bind to. For instance if you have a Car class that has two properties EngineParts and BodyParts that both return lists of Parts. You could display a tree like:

Code:
Car
 - Engine Part 1
 - Engine Part 2

Or a tree like:
Code:
Car
 - Body Part 1
 - Body Part 2


By using object binding and setting the ChildProperty of the Car binding to either the EngineParts or BodyParts property.

If however you wanted to display:

Code:
Car
  - Engine Parts
     -- Engine Part 1
     -- Engine Part 2
  - Body Parts
     -- Body Part 1
     -- Body Part 2

Then you need to provide Virtual Tree with a data model to bind to that reflects this structure. In this case you need to provide a list of child objects for the Car object that corresponds to what you want to display. So you might create a CarProperty class to represent this like:

Code:
   
    Public Class CarProperty
        Public Sub New(ByVal sName as String, ByVal sParts as IList)
              Name = sName
              Parts = sParts
        End Sub
        Public Property Name As String
        Public Property Parts As IList
    End Class


You can create Object Bindings to define how each of the individual items (Car, CarProperty and Parts) are displayed in the tree and use Programmatic binding to define the parent/child relationships.

You would handle the GetChildren event something like:

Code:
Private Sub _virtualTree_GetChildren(ByVal sender As Object, ByVal e As GetChildrenEventArgs) Handles _virtualTree.GetChildren

   If TypeOf e.Row.Item Is Car Then
       Dim sCar As Car = e.Row.Item
       Dim sList As New List(Of CarProperty)
       sList.Add(New CarProperty("Engine Parts", sCar.EngineParts))
       sList.Add(New CarProperty("Body Parts", sCar.BodyParts))
       e.Children = sList
   ElseIf TypeOf e.Row.Item Is PartList Then
       e.Children = e.Row.Item
   End If
End Sub

_________________
Infralution Support
Back to top
View user's profile Send private message Visit poster's website
EntityDev



Joined: 07 Apr 2016
Posts: 40

PostPosted: Mon Apr 18, 2016 6:39 am    Post subject: Reply with quote

Indeed, I have studied the ProgrammaticBinding sample, and I see how the Part class is constructed with both child and parent properties. I was trying to achieve something similar to the root row at each level of the tree. I see that the .Name property of your proposed 'Property' class should provide that. I wrote a class combining the elements necessary and handled the tree's GetChildren event. This is very close, but I get no child rows in the tree for the .Children property of the surrogate class.

Can you spot what the problem is? The tree is configured with just a main column (Caption = "Item") and an ObjectRowBinding (.ChildProperty = Me). I'm setting the binding type programmatically.

Code:
Public Class JobListProperty
    Private m_Caption As String
    Private m_Children As IList

    Public Property Caption As String
        Get
            Return m_Caption
        End Get
        Set(value As String)
            m_Caption = value
        End Set
    End Property

    Public Property Children As IList
        Get
            Return m_Children
        End Get
        Set(value As IList)
            m_Children = value
        End Set
    End Property

    Public Sub New()

    End Sub

    Public Sub New(caption As String, children As IList)
        m_Caption = caption
        m_Children = children
    End Sub

    Public Overrides Function ToString() As String
        Return m_Caption
    End Function
End Class


Code:
Private Sub JobListVirtualTree_GetChildren(sender As Object, e As Infralution.Controls.VirtualTree.GetChildrenEventArgs) Handles JobListVirtualTree.GetChildren
        If TypeOf e.Row.Item Is Job Then
            Dim job = DirectCast(e.Row.Item, Job)

            If job.JobLabor.Any OrElse job.Technicians.Any Then
                Dim properties As New List(Of JobListProperty)

                If job.JobLabor.Any Then properties.Add(New JobListProperty With {.Caption = "Labor", .Children = job.JobLabor})
                If job.Technicians.Any Then properties.Add(New JobListProperty With {.Caption = "Technicians", .Children = job.Technicians})

                e.Children = properties
            End If
        ElseIf TypeOf e.Row.Item Is IList Then
            e.Children = e.Row.Item
        End If
    End Sub
Back to top
View user's profile Send private message
Infralution



Joined: 28 Feb 2005
Posts: 4999

PostPosted: Mon Apr 18, 2016 7:44 am    Post subject: Reply with quote

Just to confirm - you get JobProperties displaying but not the children of this object?

Sorry I think my sample code was misleading. If you handle the GetChildren event then you take full responsibility for that part of the binding. So you must handle all the expected types (and return children for them if required). So in your case you need to add an elseif clause to handle the JobListProperty eg

Code:
 
If TypeOf e.Row.Item Is Job Then
    ...     
ElseIf TypeOf e.Row.Item Is IList Then
    e.Children = e.Row.Item
ElseIf TypeOf e.Row.Item is JobListProperty Then
    e.Children =  DirectCast(e.Row.Item, JobListProperty).Children
End If


Alternatively you can use the default object bindings for all types other than Job eg

Code:
If TypeOf e.Row.Item Is Job Then
   ...
Else
    Dim binding As RowBinding = _virtualTree.GetRowBinding(e.Row)
    e.Children = binding.GetChildrenForRow(e.Row)
End If


Your JobListProperty Object binding would therefore need to have the ChildProperty set to "Children"
_________________
Infralution Support
Back to top
View user's profile Send private message Visit poster's website
EntityDev



Joined: 07 Apr 2016
Posts: 40

PostPosted: Mon Apr 18, 2016 12:08 pm    Post subject: Reply with quote

That is correct, the tree was displaying the .ToString property of JobListProperty, but nothing deeper. Your first approach works well, thank you very much.

The alternate approach does not. I used the alternate block of code and set my existing ObjectRowBinding.ChildProperty = "Children". The tree only displays the root row (with the binding's main column Format string). I would like to understand your object model, and eventually I will.

It occurs to me that you probably assume the datasource of the tree is a collection (list) of JobListProperty, because I omitted that information. It is actually a SortableBindingList(Of Job), mostly because that's the Type I've been using all along...

I was hoping to have sorting handled by your object. So, I thought an ITypedList as the tree's datasource, along with all ITypedList .Children (they are), would be appropriate. I have little doubt my thinking on this is flawed.

Is it conventional to instead use an IList of the 'property' class as the VirtualTree's datasource?
Back to top
View user's profile Send private message
Infralution



Joined: 28 Feb 2005
Posts: 4999

PostPosted: Mon Apr 18, 2016 12:20 pm    Post subject: Reply with quote

For the alternative solution to work the Object Bindings for the other classes (other than Job) must define the ChildProperty. Since only the root row is displayed it seems that you haven't defined the ChildProperty for the root row binding - it should be set to "this" or "Me" since the root item is itself the list of children.
_________________
Infralution Support
Back to top
View user's profile Send private message Visit poster's website
EntityDev



Joined: 07 Apr 2016
Posts: 40

PostPosted: Mon Apr 18, 2016 1:27 pm    Post subject: Reply with quote

Thank you, I'll work with both methods.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Infralution Support Forum Index -> Virtual Tree Support All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group