Hello.
I use reporting together with entity framework.
Generally the structure is this:
1. I have a winform and there I select what kind of report I want to see, and also select data for the report.
2. I pass this data to report and refresh it.
I have a report that has some tables and lists inside. To pass data to those report elements I defined SetDS method for each report. For example:
public void SetDS(Product product) |
{ |
EntityTools.LoadReferences(product); |
foreach (WciFilling item in product.WciFilling) |
EntityTools.LoadReferences(item); |
foreach (WciAdditionalItem item in product.WciAdditionalItem) |
EntityTools.LoadReferences(item); |
this.DataSource = product; |
this.lstFilling.DataSource = product.WciFilling; |
this.tbGrid.DataSource = product.WciAdditionalItem.Where(o => o.WciAdditionalItemType.Id.Equals((int)EnWciAdditionalItemType.Grid)); |
} |
So, now I want to use one of these reports as a sub-report inside of list, and the question is how can I call SetDS for that subreport?
Or, maybe, I'm going in a wrong way, and there is a better approach?
Thanks.
Best regards,
Oleksandr
11 Answers, 1 is accepted
The children (inner items) of a Table/List/CrossTab item are accessible directly as if placed in the section hosting their parent (Table/List/CrossTab). You can set the DataSource of that subreport by using its DataSource property directly or bind it in its NeedDataSource event handler.
Greetings,
Steve
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
Thank you for the additional information, now it is a bit more clear what you're aiming for. However have in mind that the Table item is a separate data region (just like the subreport item) and there is no need to have it within a subreport as you can use it directly in the main report instead of the subreport item.
If your subreport has additional layout structure i.e. not only a table and you want to keep that as a separate report then you need to use the Table's NeedDataSource for binding it. I guess you want to achieve a master-detail scenario and bind the table according to some values from the main report's data, correct? Then you should proceed by using the report parameters for this purpose as explained in the Creating Master-Detail Reports Using SubReports help article. Again the Table item is similar to the SubReport item for such scenario.
You can see a similar implementations in the Product Catalog and Product Line Sales demo reports. Open them in the Visual Studio examples and review the filters of the table items.
Greetings,
Steve
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
I' m trying to use your suggestions (for now unsuccessfully), maybe I don't understand something ...
Meanwhile I will try to describe my task one more time.
1. I have such entities: Order, Product, Grid.
2. Order has collection of Product.
3. Product has collection of Grid.
So, to show all information about Order I have to:
1. Put fields of Order.
2. Put a table (or list) which will show fields of each Product. Let's call it lstProducts.
3. Put a table inside of Product table which will show fields of each Grid. Let's call it tbGrids.
Let's forget about sub-report.
1. Then, to show data in designer I create 3 project's DataSources from those 3 entities: Order, Product, Grid.
2. In report designer I set DataSource of report to ProjectNamespace.Entities.Order, I set lstProducts's DataSource to ProjectNamespace.Entities.Product and tbGrids's DataSource to ProjectNamespace.Entities.Grid.
3. To show actual data I need to set DataSources of all items mentioned in 2nd step in runtime. So, from the form that contains report I:
3.1. set report's DataSource to some Order object (let's call it order).
3.2. set lst.DataSource = order.Products
3.3. and here is the question: I need to set tbGrid.DataSource, but it should change for each Product which is inside of order.Products collection. And I don't see any way how to do this.
I've attached a sample report with two nested tables to show you how to accomplish such scenario. Give it a spin and let me know if further help is needed.
Sincerely yours,
Steve
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
I think you should put it to your samples.
Description:
I have MainTable which shows the list of CareAreas.
Inside Main Table i have another table called Detaildetable1 which shows the list of Questions.and Inside the DetailTable1
There is one more table DetailTable2, which shows the Resident's Information.
I have created 3 classes.
public class CareAreaDetail
{
private String _care;
private QCIDetail[] _qci;
public String CareAreaQCITag
{
get
{
return _care;
}
set
{
_care = value;
}
}
public QCIDetail[] qci
{
get
{
return _qci;
}
set
{
_qci = value;
}
}
}
public class QCIDetail
{
private String _qcisn;
private ResidentDetail[] _resindet;
public String QuestionShortName
{
get { return _qcisn; }
set { _qcisn = value; }
}
public ResidentDetail[] resDetail
{
get
{
return _resindet;
}
set
{
_resindet = value;
}
}
}
public class ResidentDetail
{
private String _resident, _room;
private DateTime _adate;
//public String QuestionShortName { get;set;}
public String ResidentName
{
get
{
return _resident;
}
set
{
_resident = value;
}
}
public String Room
{
get
{
return _room;
}
set
{
_room = value;
}
}
public DateTime AssessmentDate
{
get
{
return _adate;
}
set
{
_adate = value;
}
}
}
Now on Main Table's NeedDataSource event i have assigned the Array Object of CareAreaDetail Class.
For DetailedTable1's needdatasource property i have assigned QCIDetailed Class object and for DetailTable2, ResidentDetail class object.
Now where report is generated it shows proper Data in MainTable. bt in DetailTable1 and DetailTable2 it shows the same data for all the rows. i.e. for DetailTable1 it shows the data at index 0 in the QCITable class array in all rows and
for DetailTable2 it shows the data at index 0 in the ResidentDetail class array.
Here is the code.
private void DetailTable2_NeedDataSource_1(object sender, EventArgs e)
{
Processing.Table table = (Processing.Table)sender;
DetailTable2.DataSource = table.DataObject["resDetail"];
}
private void DetailTable1_NeedDataSource_1(object sender, EventArgs e)
{
Processing.Table table = (Processing.Table)sender;
DetailTable1.DataSource = table.DataObject["qci"];
}
private void MainTable_NeedDataSource_1(object sender, EventArgs e)
{
DataTable dt = GetAllResponses();
DataTable DistinctCareAreaTable = SelectDistinct(dt, "CareArea");
CareAreaDetail[] cad = new CareAreaDetail[DistinctCareAreaTable.Rows.Count];
int i = 0;
foreach (DataRow row in DistinctCareAreaTable.Rows)
{
cad[i] = new CareAreaDetail();
cad[i].CareAreaQCITag = "Care Area: " + row[0].ToString().Trim() + " (" + dt.Select("CareArea='" + row[0].ToString().Trim() + "'")[0]["QuestionTag"].ToString() + ")";
DataTable dtTemp = dt.Copy();
dtTemp.Clear();
DataRow[] TempDataRow = dt.Select("CareArea='" + row[0].ToString() + "'");
foreach (DataRow dr in TempDataRow)
dtTemp.LoadDataRow(dr.ItemArray, false);
DataTable DistinctQCITable = SelectDistinct(dtTemp, "QuestionShortName");
QCIDetail[] qd = new QCIDetail[DistinctQCITable.Rows.Count];
int j = 0;
foreach (DataRow drQCI in DistinctQCITable.Rows)
{
qd[j] = new QCIDetail();
qd[j].QuestionShortName = drQCI[0].ToString();
DataRow[] ResidentDataRow = dt.Select("QuestionShortName='" + drQCI[0].ToString() + "'");
ResidentDetail[] resDetail = new ResidentDetail[ResidentDataRow.Length];
int k = 0;
foreach (DataRow drRes in ResidentDataRow)
{
resDetail[k] = new ResidentDetail();
resDetail[k].ResidentName = drRes["Resident"].ToString();
resDetail[k].Room = drRes["Room"].ToString();
resDetail[k].AssessmentDate = (DateTime)drRes["AssessmentDate"];
k++;
}
qd[j].resDetail = resDetail;
j++;
}
cad[i].qci = qd;
i++;
}
Processing.Table table = (Processing.Table)sender;
table.DataSource = cad; // DATA assigned in the datasource is accurate and in proper format.
}
I have attached Image of that report.
There was similar bug we introduced in the Q3 release that we immediately fixed in internal build available for download in your account. Please upgrade and let us know how it goes.
All the best,
Steve
the Telerik team
The Master1 entry has its correct details (Detail1-3), but every other Master has the same details, instead of showing their own. It seems the table_NeedDataSource event is only triggered once and reuses the same DataSource for every nested table.
So how can I tell the sub-report to use its master's details?
I need to display a list of details in a cell based on its row and column groups, and I think this may be a good way to do it.
I've attached modified version of the TestReport. The only single difference is that you need to place the inner table in a Panel item in order to get the correct data context from the main table. This is required due to the data driven nature of the table and a change we did in Q2 2010, namely the Telerik.Reporting.Processing.TableCell object is removed.
Kind regards,
Steve
the Telerik team