CodeSmith Community
Your Code. Your Way. Faster!

DataGridView parent/child databinding

Latest post 01-25-2007 8:31 AM by RCouchman. 2 replies.
  • 01-23-2007 2:19 PM

    • RCouchman
    • Not Ranked
    • Joined on 02-15-2006
    • Posts 5
    • Points 175

    DataGridView parent/child databinding

    I have a form with two DataGridView controls, the first shows Orders and the second shows OrderDetails for the selected order.  I've created BindingSources and attached them like this:

       OrdersService ordersService = new OrdersService();
       TList<Orders> orders = ordersService.GetAll();
       ordersService.DeepLoad(orders,false,DeepLoadType.IncludeChildren,typeof(TList<OrderDetails>));

       BindingSource bsOrders = new BindingSource();
       bsOrders.DataSource = orders;

       BindingSource bsOrderDetails = new BindingSource();
       bsOrderDetails.DataSource = bsOrders;
       bsOrderDetails.DataMember = "OrderDetailsCollection";

       this.dgvOrders.DataSource = bsOrders;
       this.dgvOrderDetails.DataSource = bsOrderDetails;

    The Orders grid shows ok, but the OrderDetails is blank - no rows, no columns.  The bindingsource for the details seems to be doing what it should, looking at it with the debugger shows it containing only the child records for the selected parent.  Also checked the bindingsources with this bit of code and they look to be working.

       int i = 0;
       while (i < bsOrders.Count) {
        Orders o = (Orders)bsOrders.Current;
        Console.WriteLine("Parent - OrderID: {0}\tCustomerID: {1}",o.OrderID,o.CustomerID);

        int j = 0;
        while (j < bsOrderDetails.Count) {
         OrderDetails od = (OrderDetails)bsOrderDetails.Current;
         Console.WriteLine("\tChild - OrderID: {0}\tUnitPrice: {1}",od.OrderID,od.UnitPrice);
         bsOrderDetails.MoveNext();

         j++;
        }

        bsOrders.MoveNext();
        i++;
       }

     Any help on correctly binding the child grid would be greatly appreciated.

    Thanks, Richard

    Filed under:
    • Post Points: 35
  • 01-24-2007 11:49 PM In reply to

    Re: DataGridView parent/child databinding

    Hi,

    You have to make your child binding source's DataSource property point to the parent BindingSource.

    so

    bsOrders.DataSource = someTList; 

    bsOrderDetails.DataSource = bsOrders;
    bsOrderDetails.DataMember = "OrderDetails";  

     You can google something like Master Detail Binding Source, and there should be plenty of examples.
     


    Robert Hinojosa
    -------------------------------------
    Member of the Codesmith Tools, .netTiers, teams
    http://www.nettiers.com
    -------------------------------------
    • Post Points: 35
  • 01-25-2007 8:31 AM In reply to

    • RCouchman
    • Not Ranked
    • Joined on 02-15-2006
    • Posts 5
    • Points 175

    Re: DataGridView parent/child databinding

    Robert,

    Thanks for the reply, and for your netTiers work too.

    I have the child binding source configured as you suggest - bsChild.DataSource = bsParent, and bsChild.DataMember = "ParentPropertyReturningChildList".  Since the original post, I found this article on Code Project that shows how to use parent/child DataGridViews with business objects.

    I followed that approach, which creates a DataSource from the Orders entity, dragged Orders to the parent grid, and OrderDetailsCollection to the child grid, and the ide created the binding sources and the columns in the grids.  When I load the TList and assign the datasource/datamember to the bindingsources, the parent grid shows cell values as expected, but the child grid shows the correct number of rows for the selected parent, but all the child cells are blank.  In order to get the child grid to display values, I had to handle CellFormatting, basically extracting the underlying values from the child bindingsource and assigning the cell value.

     

      private void dgOrderDetails_CellFormatting(object sender,DataGridViewCellFormattingEventArgs e) {
       if (e.RowIndex < this.orderDetailsCollectionBindingSource.Count) {
        OrderDetails od = (OrderDetails)this.orderDetailsCollectionBindingSource[e.RowIndex];
        if (od != null) {
         PropertyDescriptorCollection props = TypeDescriptor.GetProperties(od);
         PropertyDescriptor desc = props.Find(this.dgOrderDetails.Columns[e.ColumnIndex].DataPropertyName,true);

         e.Value = desc.GetValue(od);
        }
       }
      }

     

    It seems like I'm missing something real basic here.  If anyone has a working example of binding a deeploaded entity to a pair of parent/child DataGridViews, I'd appreciate taking a look at it.

    Thanks again.

    • Post Points: 5
Page 1 of 1 (3 items) | RSS
Copyright © 2008 CodeSmith Tools, LLC
Powered by Community Server (Commercial Edition), by Telligent Systems