Link to home
Start Free TrialLog in
Avatar of Mark Bakelaar
Mark BakelaarFlag for Norway

asked on

How do I add parent information to a datagridview bound to a child datatable

Hi,
I have two datatables with a datarelation. The child table is bound to a datagridview and I have added an ubound text column. In this ubound text column I want to display parent information of the child row.

Do anyone have a code snippet or link on how to do this?

Best regards, Mark
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

If you have a DataRow object, then you can get the parent DataRow with DataRow.GetParentRow().
You can do it pretty easily.  Here's an example:

        'Create a DataSet
        Dim ds As New DataSet()

        'Create a Parent Table, add ID and Text columns
        Dim parTable As New DataTable("ParentTable")
        parTable.Columns.Add("ID")
        parTable.Columns.Add("Text")

        'Add 1 row to the Parent table
        parTable.Rows.Add("1", "Parent 1")

        'Create a ChildTable, add ParentID and Item columns
        Dim childTable As New DataTable("ChildTable")
        childTable.Columns.Add("ParentID")
        childTable.Columns.Add("Item")

        'Add 5 rows to the child table
        For i As Int16 = 1 To 5
            childTable.Rows.Add("1", "Item " & i)
        Next

        'Add Parent Table and Child Table to the DataSet
        ds.Tables.Add(parTable)
        ds.Tables.Add(childTable)

        'Create a Relation between the Child and Parent tables
        Dim rel As DataRelation = ds.Relations.Add("Child_Parent", _
             childTable.Columns("ParentID"), _
             parTable.Columns("ID"), _
             False)

        'Create a BindingSource for the Child DataTable
        Dim bsChild As New BindingSource()
        bsChild.DataMember = "ChildTable"
        bsChild.DataSource = ds

        'Set the Child BindingSource as the DataSource for the DataGridView
        Me.DataGridView1.DataSource = bsChild

        'Create a Parent BindingSource
        Dim bsParent As New BindingSource()
        bsParent.DataSource = bsChild
        bsParent.DataMember = "Child_Parent"

        'Bind the TextBox to the Parent BindingSource
        Me.TextBox1.DataBindings.Add("Text", bsParent, "Text")

Avatar of Mark Bakelaar

ASKER

Thanks LearnedOne for your replay,
I am not sure how to implement it. The result I want is one datagridview with most columns bound to the childtable, but for additional reference I want to add some more unbound columns that show parentrow information. I do not want to show any hierarchie, just additional information.

In your replay what event of the DataGridView triggers the code "DataRow.GetParentRow". I thought that for instance the event "CellFormatting" should be triggered on a change of a datagridrow and that the code could be placed in this event, but maybe the solution is more simple...

Can you give me some more detail? Best regards, Mark
If you have an unbound mode, then are you handling the CellValueNeeded event?
Thanks again, is this the event that is triggered if a value in the datagridview is changed and that I can use to put the code in that retrieves the parentrow information that I can put in the unbound column?
That is the event that is triggered when VirtualMode = True.
Thanks LearnedOne,
I need to read up to understand more about virtualmode, but just to be sure: this is the prefered solution for a mixed bound and unbound datagridview to fill the unbound columns?
Regards, Mark

 
ASKER CERTIFIED SOLUTION
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I have red up on the Virtual Mode and CellValueNeeded event and have played around with it in Visual Studio. I do have some questions. You mentioned that it is not possible to mix bound and unbound. Is the basic idea then to:
- Set the DataDridView.VirtualMode = true
- Add columns to the DataGridView
- Set the eventhandler CellValueNeeded. Using the RowIndex and ColumnIndex values from the DataTable can be retrieved (RowIndex DataGridView = RowIndex.childtable.
(The steps are shown in the code below, even if it does not work yet)

My questions (a direction is enough):
- Is the above correct?
- How do I set the number of rows to be displayed dynamically?
- The following link seems to claim that bound and unbound can be combined http://arsalantamiz.blogspot.com/2008/04/how-to-display-row-icon-in-datagridview.html.

Regards, Mark
Code in the load event I tried:
        'START BUILDING TABPAGES
        Dim ShipperColumn As GridViewTextBoxColumn
        ShipperColumn = New GridViewTextBoxColumn()
        ShipperColumn.HeaderText = "Shipper"
 
        For Each HatchTab As TabItem In Me.TabStripHatches.Items
            For Each Ctrl As Control In HatchTab.ContentPanel.Controls
                If TypeOf Ctrl Is RadGridView Then
                    With TryCast(Ctrl, RadGridView)
                        .VirtualMode = True
                        '.DataSource = objDataSet.Tables("ASNs")
                        .Columns.Add(ShipperColumn)
 
CellValueNeeded event:
Private Sub dgvHatch4Hatchplan_CellValueNeeded(ByVal sender As Object, ByVal e As Telerik.WinControls.UI.GridViewCellValueEventArgs) Handles dgvHatch4Hatchplan.CellValueNeeded
        Debug.WriteLine("Is this event triggered?")
        Debug.WriteLine("Column " & e.ColumnIndex.ToString)
        Debug.WriteLine("Row " & e.RowIndex.ToString)
        If e.RowIndex >= 0 Then 'AndAlso e.ColumnIndex = Me.TaskStatusIconColumn.Index Then
            e.Value = e.RowIndex 'This needs to retrieve data from datatable

Open in new window

You need to set RowCount to set the number of rows that you are going to need.  

Also, you didn't say that you are really using the Telerik WinControls.
Thanks a lot for your help, I learned something new this weekend. As for the RadControls, I test everything with WinControls and then convert some to RadControls (especially GridViews). Apologies for not mentioning this. Regards, Mark