Home Forums WinForms controls Xceed Grid for WinForms Master detail using collections

Viewing 13 posts - 1 through 13 (of 13 total)
  • Author
    Posts
  • User (Old forums)
    Member
    Post count: 23064
    #15175 |

    Hello,

    I am trying to show a bound master detail relationship between two collections. I have a master collection called products. Each item in the product collection has it’s own collection called Features.

    I wanted to set up the grid so that the master table shows all of the products and the details show all of the features for each product.

    Each feature item contains a property called ProductID, which is also in each Product Item that can be used to link them.

    Thanks..

    ..Joe..

    Imported from legacy forums. Posted by Testing (had 9614 views)

    User (Old forums)
    Member
    Post count: 23064

    This is possible. What you need is to have a “Feature” property (field) within the Products collection which in fact contains the Features collection. So each product will have its own Feature list. This is how the relationship is established between two lists. Then you bind the grids the following way :

    Master.SetDataBinding( Products, “” );
    Detail.SetDataBinding( null, “Features” );

    Imported from legacy forums. Posted by André (had 4210 views)

    User (Old forums)
    Member
    Post count: 23064

    Thanks,

    it worked perfectly.

    Imported from legacy forums. Posted by Testing (had 666 views)

    User (Old forums)
    Member
    Post count: 23064

    hi
    i have one question about type of collection to use in such kind of master-detail grids.
    In my application i use collection TradersList inherited from BindingList<TraderSO>
    TraderSO have property DetailsSymbol, which is SymbolList collection inherited from BindingList<SymbolSO>
    TradersList and SymbolList implements ITypedList interface

    in application i set binding use following code
    TSO = new TradersList();
    gridTSO.SetDataBinding(TSO, “”);
    detailGridTSO_S.SetDataBinding(null, “DetailsSymbol”);

    when application run i can’t access to columns of detail grid and when i add new row to detail collection, grid does not show it (i must UpdateDetailsGrid method to show it)

    Can you give me advise how to solve this problem?
    Or maybe i am wrong with collections i use?

    Best Regards
    Fedir

    Imported from legacy forums. Posted by Fedir (had 555 views)

    User (Old forums)
    Member
    Post count: 23064

    And one more obout previous issue

    when i start with empty collection and add first member i get

    “The data source of all the synchronized detail grids must have the same number of fields.”
    I think problem is that detail grid does not initialize his columns.

    Best Regard
    Fedir

    Imported from legacy forums. Posted by Fedir (had 673 views)

    User (Old forums)
    Member
    Post count: 23064

    For the first problem, you are probably using the detail grid template instead of the detail grid instance of the master row where you want to add a new row. You can access the specific instance when the form is first loaded through the InitializingDetailGrid event, or thought the DetailGrids collection on the DataRow.

    e.g.:

    Xceed.Grid.DataRow detailRow = gridControl1.DataRows[0].DetailGrids[0].DataRows.AddNew();

    As for the second problem, this is because there is probably no column in the collection when it is empty, so the grid cannot generate the corresponding columns. Either you make sure you always have something in the collection, or you can set the SynchronizeDetailGrids property on the GridControl to false.

    Imported from legacy forums. Posted by André (had 568 views)

    User (Old forums)
    Member
    Post count: 23064

    Thank You.

    Imported from legacy forums. Posted by Fedir (had 5400 views)

    User (Old forums)
    Member
    Post count: 23064

    « This is possible. What you need is to have a “Feature” property (field)
    within the Products collection which in fact contains the Features
    collection. So each product will have its own Feature list. This is how
    the relationship is established between two lists. Then you bind the
    grids the following way :

    Master.SetDataBinding( Products, “” );
    Detail.SetDataBinding( null, “Features” ); »

     

    Hi

      I understand the concept but I don’t know how to do that (the field which is a collection).  I use the dataset designer in Visual Studio 2008.  I have 2 linked tables (relation).  If possible, I would like to use the automaticly generated bindingsource and tableadapter.

     Regards

    Imported from legacy forums. Posted by Daniel (had 455 views)

    User (Old forums)
    Member
    Post count: 23064

    What I described applies to a list, not to a DataSet.  If you design two DataTable, then you can simply add a relationship between the two table on a common field, and the grid will be able to show the hierarchical data.

    e.g.:  Assume two data tables, Supplier (master) and Product (detail), and a relationship between the two on the SupplierID field called “SupplierProduct”.  Assume a DataSet build form those tables called SPDataSet.

    Master.SetDataBinding( SPDataSet.Supplier, “” );

    Detail.SetDataBinding( SPDataSet.Supplier, “SupplierProduct” );

    Here is more information from our help documentation :

    http://doc.xceedsoft.com/products/XceedGrid/Data_binding.html
    http://doc.xceedsoft.com/products/XceedGrid/Creating%20a%20dataset%20using%20the%20BindingSource%20class.html
    http://doc.xceedsoft.com/products/XceedGrid/Master_Detail.html
    http://doc.xceedsoft.com/products/XceedGrid/Building_a_bound_hierarchical_master_detail_grid.html

    Imported from legacy forums. Posted by André (had 4504 views)

    User (Old forums)
    Member
    Post count: 23064

    [quote user=”André”]

    What I described applies to a list, not to a DataSet.  If you design two DataTable, then you can simply add a relationship between the two table on a common field, and the grid will be able to show the hierarchical data.

    e.g.:  Assume two data tables, Supplier (master) and Product (detail), and a relationship between the two on the SupplierID field called “SupplierProduct”.  Assume a DataSet build form those tables called SPDataSet.

    Master.SetDataBinding( SPDataSet.Supplier, “” );

    Detail.SetDataBinding( SPDataSet.Supplier, “SupplierProduct” );

    Here is more information from our help documentation :

    http://doc.xceedsoft.com/products/XceedGrid/Data_binding.html
    http://doc.xceedsoft.com/products/XceedGrid/Creating%20a%20dataset%20using%20the%20BindingSource%20class.html
    http://doc.xceedsoft.com/products/XceedGrid/Master_Detail.html
    http://doc.xceedsoft.com/products/XceedGrid/Building_a_bound_hierarchical_master_detail_grid.html

    [/quote]

    The problem is it is very slow.  I read on another post to set add detailGrid to collapsed (and it is what I want) and to bind the opened detail grid only when the event CollapsedChanged is fired.  I have acheived with unbound detail grid but I didn’t succeded with bounded detail grid.

    Daniel

    Imported from legacy forums. Posted by Daniel (had 367 views)

    User (Old forums)
    Member
    Post count: 23064

    I find a solution.  I create as many dataTable as many detail grid is opened.  Don’t know if there a better way to do the same thing.  I don’t really like my code, but this works, and it’s fast. (Note many lines are removed)

    Public Class frm_catalog

        Dim catalogPriceDT As Collection ‘ gestionSEDataSet.catalog_PriceDataTable
        Dim catalogPriceBS As Collection ‘ BindingSource
        Dim catalogPriceTA As gestionSEDataSetTableAdapters.catalog_PriceTableAdapter

        Public Sub New()
            InitializeComponent()

            catalogPriceTA = New gestionSEDataSetTableAdapters.catalog_PriceTableAdapter
            catalogPriceDT = New Collection
            catalogPriceBS = New Collection
        End Sub

        Private Sub template_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Me.Catalog_listTableAdapter.FillByIdCie(Me.GestionSEDataSet.catalog_list, getIdCie())

                With GridCatalog
                    .BeginInit()
           
                    .DetailGridTemplates(0).Collapsed = True
                    .SynchronizeDetailGrids = False
                    AddHandler .DetailGridTemplates(0).CollapsedChanged, AddressOf bindDetailGrid
                    .UpdateDetailGrids()
                    end with
            end sub
           
        Private Sub bindDetailGrid(ByVal sender As System.Object, ByVal e As System.EventArgs)
            Dim LocalDetail As Xceed.Grid.DetailGrid

            LocalDetail = DirectCast(sender, Xceed.Grid.DetailGrid)
            If Not LocalDetail.Collapsed Then
                Try
                    Dim DT As gestionSEDataSet.catalog_PriceDataTable = New gestionSEDataSet.catalog_PriceDataTable

                    Dim BS As BindingSource = New BindingSource
                    BS.DataSource = DT
                    catalogPriceTA.FillByIdCatalog(DT, LocalDetail.ParentDataRow.Cells(“id_catalog”).Value)

                    ‘ default value for linking field
                    DT.Columns(“id_catalog”).DefaultValue = LocalDetail.ParentDataRow.Cells(“id_catalog”).Value

                    catalogPriceDT.Add(DT)
                    catalogPriceBS.Add(BS)

                    With LocalDetail
                        .SetDataBinding(BS, Nothing)
                                    end with

                Catch ex As Exception
                    Call ErrorManagement(Me.Name, “detailGridTemplate1_CollapsedChanged”, ex.Message)
                End Try
            End If
        End Sub

        Private Sub save()
            Me.Validate()
            Me.Catalog_listBindingSource.EndEdit()
            Me.Catalog_listTableAdapter.Update(Me.GestionSEDataSet.catalog_list)

            For Each BS As BindingSource In catalogPriceBS
                BS.EndEdit()
            Next

            For Each DT As gestionSEDataSet.catalog_PriceDataTable In catalogPriceDT
                catalogPriceTA.Update(DT)
            Next

        End Sub

    Imported from legacy forums. Posted by Daniel (had 496 views)

    User (Old forums)
    Member
    Post count: 23064

    This seems fine.  The only thing that could be done differently is to load all the data into you DataSet when first loading your form, and then simply bind the detail girds as it gets expended.

    e.g.:

        private void Form1_Load( object sender, EventArgs e )
        {
         
          detailGridTemplate1.Collapsed = true;
          detailGridTemplate1.CollapsedChanged += new EventHandler( detailGridTemplate1_CollapsedChanged );
         
          gridControl1.SynchronizeDetailGrids = false;

          gridControl1.SetDataBinding( this.northwindDataSet.Suppliers, “” );

          //Assuming a Suppliers (master) / Products (detail) relationship called “SuppliersProducts” in the DataSet.
          this.suppliersTableAdapter.Fill( this.northwindDataSet.Suppliers );
          this.productsTableAdapter.Fill( this.northwindDataSet.Products );
        }

        void detailGridTemplate1_CollapsedChanged( object sender, EventArgs e )
        {
          DetailGrid grid = sender as DetailGrid;
          if( !grid.Collapsed )
            //This will permit to fill the DetailGrid with the data related to the parent row, by using the relationship
            grid.SetDataBinding( grid.ParentDataRow.Cells[ “SuppliersProducts” ].Value, string.Empty );
          else
            grid.SetDataBinding( null, string.Empty );     
        }

    Imported from legacy forums. Posted by André (had 4374 views)

    User (Old forums)
    Member
    Post count: 23064

    [quote user=”André”]

    This seems fine.  The only thing that could be done differently is to load all the data into you DataSet when first loading your form, and then simply bind the detail girds as it gets expended.

    e.g.:

        private void Form1_Load( object sender, EventArgs e )
        {
         
          detailGridTemplate1.Collapsed = true;
          detailGridTemplate1.CollapsedChanged += new EventHandler( detailGridTemplate1_CollapsedChanged );
         
          gridControl1.SynchronizeDetailGrids = false;

          gridControl1.SetDataBinding( this.northwindDataSet.Suppliers, “” );

          //Assuming a Suppliers (master) / Products (detail) relationship called “SuppliersProducts” in the DataSet.
          this.suppliersTableAdapter.Fill( this.northwindDataSet.Suppliers );
          this.productsTableAdapter.Fill( this.northwindDataSet.Products );
        }

        void detailGridTemplate1_CollapsedChanged( object sender, EventArgs e )
        {
          DetailGrid grid = sender as DetailGrid;
          if( !grid.Collapsed )
            //This will permit to fill the DetailGrid with the data related to the parent row, by using the relationship
            grid.SetDataBinding( grid.ParentDataRow.Cells[ “SuppliersProducts” ].Value, string.Empty );
          else
            grid.SetDataBinding( null, string.Empty );     
        }

    [/quote]

    This is what I was trying to do, without succes.  When setting the synchronizeDetailGrids to false, it was always showing me the first result (bad relationship).

    I have tried another time this morning and now all works fine.  Thanks you for your help and your patience.

    Imported from legacy forums. Posted by Daniel (had 5492 views)

Viewing 13 posts - 1 through 13 (of 13 total)
  • You must be logged in to reply to this topic.