Home › Forums › WinForms controls › Xceed Grid for WinForms › Master detail using collections
-
AuthorPosts
-
#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)
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)
Thanks,
it worked perfectly.
Imported from legacy forums. Posted by Testing (had 666 views)
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 interfacein 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
FedirImported from legacy forums. Posted by Fedir (had 555 views)
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
FedirImported from legacy forums. Posted by Fedir (had 673 views)
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)
Thank You.
Imported from legacy forums. Posted by Fedir (had 5400 views)
« 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)
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.htmlImported from legacy forums. Posted by André (had 4504 views)
[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)
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_PriceTableAdapterPublic Sub New()
InitializeComponent()catalogPriceTA = New gestionSEDataSetTableAdapters.catalog_PriceTableAdapter
catalogPriceDT = New Collection
catalogPriceBS = New Collection
End SubPrivate 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.DetailGridLocalDetail = DirectCast(sender, Xceed.Grid.DetailGrid)
If Not LocalDetail.Collapsed Then
Try
Dim DT As gestionSEDataSet.catalog_PriceDataTable = New gestionSEDataSet.catalog_PriceDataTableDim 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”).ValuecatalogPriceDT.Add(DT)
catalogPriceBS.Add(BS)With LocalDetail
.SetDataBinding(BS, Nothing)
end withCatch ex As Exception
Call ErrorManagement(Me.Name, “detailGridTemplate1_CollapsedChanged”, ex.Message)
End Try
End If
End SubPrivate 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()
NextFor Each DT As gestionSEDataSet.catalog_PriceDataTable In catalogPriceDT
catalogPriceTA.Update(DT)
NextEnd Sub
Imported from legacy forums. Posted by Daniel (had 496 views)
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)
[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)
-
AuthorPosts
- You must be logged in to reply to this topic.