Hi,
I would like to know how to access the Fields.Item equivalent for a collection of complex objects. Unless I am overlooking something, the documentation for expressions is woefully inadequate. Where does the documentation mention the use of Fields.Item and other available api? The only time I have seen any mention of the use of these api is in replies to forum posts and these are few indeed. Most of the replies that mention it are from Steve (many thanks for those).
In any case, what I am trying to do is pass the current list item data context to a method on the report data source object. The data source object exposes a list of complex objects that are used as the data source for a list in the report. The method call occurs when a table grouping expression is evaluated.
Expression example:
If I can access the "Fields.Item" object everything works but of course it only works for objects such as strings.
I am using the latest version of the telerik controls (Q1 2013 build 7.0.13.228).
Thanks,
Tom
I would like to know how to access the Fields.Item equivalent for a collection of complex objects. Unless I am overlooking something, the documentation for expressions is woefully inadequate. Where does the documentation mention the use of Fields.Item and other available api? The only time I have seen any mention of the use of these api is in replies to forum posts and these are few indeed. Most of the replies that mention it are from Steve (many thanks for those).
In any case, what I am trying to do is pass the current list item data context to a method on the report data source object. The data source object exposes a list of complex objects that are used as the data source for a list in the report. The method call occurs when a table grouping expression is evaluated.
Expression example:
"=ReportItem.Report.DataSource.MyMethod(Fields.Item)"
If I can access the "Fields.Item" object everything works but of course it only works for objects such as strings.
I am using the latest version of the telerik controls (Q1 2013 build 7.0.13.228).
Thanks,
Tom
9 Answers, 1 is accepted
0
Hello Thomas,
Thank you for the provided information. We are currently aware that our documentation lacks those tiny bits of information. You can rest assured that this is logged into our system and at some point we will add more information regarding master-detail scenarios and handling hierarchical structures in general.
Up to your question: you can use user-defined function accepting a collection of items of specific type. If the collection is nested for the current data source, it would appear as a field, e.g. Field.MyList:
Please check the attached sample report.
If you need further help, please send us a runnable sample illustrating your scenario and problem, so we can provide you with more accurate suggestions.
Greetings,
Stef
the Telerik team
Thank you for the provided information. We are currently aware that our documentation lacks those tiny bits of information. You can rest assured that this is logged into our system and at some point we will add more information regarding master-detail scenarios and handling hierarchical structures in general.
Up to your question: you can use user-defined function accepting a collection of items of specific type. If the collection is nested for the current data source, it would appear as a field, e.g. Field.MyList:
class MyObject
{
public List<MySubObject
> MyList { get; set; }
}
If you need further help, please send us a runnable sample illustrating your scenario and problem, so we can provide you with more accurate suggestions.
Greetings,
Stef
the Telerik team
Have you tried the new visualization options in Telerik Reporting Q1 2013? You can get them from your account.
0
Thomas
Top achievements
Rank 1
answered on 26 Apr 2013, 06:59 PM
Hi Stef,
Thank you for the reply.
I don't believe the solution presented correctly answers the question. You suggest passing a list of data objects as an additional property on the current data object. What I needed to do was pass the current data object to a method. The report detail list data source is bound to a collection of data objects and as the detail data is generated, the current data object would be passed to the method at that time.
That being said, I was able to accomplish what I needed to do by passing multiple property values, from the current data object, to the method on the report data source. The report data source holds the reference to the collection of data objects used to populate the detail data. The end result of what I needed, in this instance, was to uniquely identify the current data object within the collection of data objects.
To elaborate on the intent, the expressions are dynamically generated in the report OnNeedDataSource method and are used to define the RowGroups and ColumnGroups of the report. Dynamically generating the expressions allows them to be strongly typed and easily re-factored if needed.
Expression example:
Cheers,
Tom
Thank you for the reply.
I don't believe the solution presented correctly answers the question. You suggest passing a list of data objects as an additional property on the current data object. What I needed to do was pass the current data object to a method. The report detail list data source is bound to a collection of data objects and as the detail data is generated, the current data object would be passed to the method at that time.
That being said, I was able to accomplish what I needed to do by passing multiple property values, from the current data object, to the method on the report data source. The report data source holds the reference to the collection of data objects used to populate the detail data. The end result of what I needed, in this instance, was to uniquely identify the current data object within the collection of data objects.
To elaborate on the intent, the expressions are dynamically generated in the report OnNeedDataSource method and are used to define the RowGroups and ColumnGroups of the report. Dynamically generating the expressions allows them to be strongly typed and easily re-factored if needed.
Expression example:
=ReportItem.Report.DataSource.MyMethod(Fields.MyProperty1 + ',' + Fields.MyProperty2) ...
Cheers,
Tom
0
Hello Thomas,
The current bound data is available through the ReportItem.DataObject which can be passed to a user-defined function which is not mapped to the data source of the report.
If you need further help, please send us more details about the passed data, dynamically created items, expressions and their use, or even better post your code, so we can understand the scenario.
Kind regards,
Stef
the Telerik team
The current bound data is available through the ReportItem.DataObject which can be passed to a user-defined function which is not mapped to the data source of the report.
If you need further help, please send us more details about the passed data, dynamically created items, expressions and their use, or even better post your code, so we can understand the scenario.
Kind regards,
Stef
the Telerik team
Have you tried the new visualization options in Telerik Reporting Q1 2013? You can get them from your account.
0
Thomas
Top achievements
Rank 1
answered on 01 May 2013, 04:54 PM
Hi Stef,
I think the original question I posted clearly states the scenario. When binding a list to a collection of items, you can access individual properties of the current data context (meaning data object of the current item in the list) using the Fields.MyProperty expression. Using the Fields.Item expression you can access the data context of the current item in the list. But this expression only works for simple types such as string or int. My question asked if there is a similar method for accessing the data context of the current list item when the data context is a complex type.
The ReportItem.DataObject expression you suggested does not return the current list item data context. If it was the list item data context the expression ReportItem.DataObject.MyProperty would be equivalent to Fields.MyProperty and it is not.
Based on similar forum threads, researching, and trial and error I come to the conclusion it is not possible. As I said in my previous reply, I found a workaround and was able to accomplish the task that was required.
Cheers,
Tom
I think the original question I posted clearly states the scenario. When binding a list to a collection of items, you can access individual properties of the current data context (meaning data object of the current item in the list) using the Fields.MyProperty expression. Using the Fields.Item expression you can access the data context of the current item in the list. But this expression only works for simple types such as string or int. My question asked if there is a similar method for accessing the data context of the current list item when the data context is a complex type.
The ReportItem.DataObject expression you suggested does not return the current list item data context. If it was the list item data context the expression ReportItem.DataObject.MyProperty would be equivalent to Fields.MyProperty and it is not.
Based on similar forum threads, researching, and trial and error I come to the conclusion it is not possible. As I said in my previous reply, I found a workaround and was able to accomplish the task that was required.
Cheers,
Tom
0
Hello Thomas,
You statement that ReportItem.DataObject.MyProperty is not equivalent to Fields.MyProperty is not correct. On the contrary, they are mutually replaceable and return the same value. You can easily test that with the ListBoundReport report from the sample class library installed with the product. For example, you can replace
=Fields.Manufacturer
with
=ReportItem.DataObject.Manufacturer
and the result will be the same.
If you are using an array of simple types as a data source, e.g. int[], string[], you can access the data item via Fields.Item or ReportItem.DataObject.Item.
In this context the expression in your original question should be:
"=ReportItem.Report.DataSource.MyMethod(ReportItem.DataObject)"
although our advice is to use a user function instead of a method of the data source object.
The possible reasons why the expression could not be working is that either the data source object does not have a method called MyMethod, or the argument of the MyMethod method is not of the correct type. The easiest way to verify this issue is to change the argument's type to System.Object. For example:
Still, the exact reason can be found much easier if you can send us the error message which you receive when running your report.
Hope this helps.
Regards,
Chavdar
the Telerik team
You statement that ReportItem.DataObject.MyProperty is not equivalent to Fields.MyProperty is not correct. On the contrary, they are mutually replaceable and return the same value. You can easily test that with the ListBoundReport report from the sample class library installed with the product. For example, you can replace
=Fields.Manufacturer
with
=ReportItem.DataObject.Manufacturer
and the result will be the same.
If you are using an array of simple types as a data source, e.g. int[], string[], you can access the data item via Fields.Item or ReportItem.DataObject.Item.
In this context the expression in your original question should be:
"=ReportItem.Report.DataSource.MyMethod(ReportItem.DataObject)"
although our advice is to use a user function instead of a method of the data source object.
The possible reasons why the expression could not be working is that either the data source object does not have a method called MyMethod, or the argument of the MyMethod method is not of the correct type. The easiest way to verify this issue is to change the argument's type to System.Object. For example:
public
string
MyMethod(
object
obj)
{
return
obj.GetType().ToString();
}
Still, the exact reason can be found much easier if you can send us the error message which you receive when running your report.
Hope this helps.
Regards,
Chavdar
the Telerik team
Have you tried the new visualization options in Telerik Reporting Q1 2013? You can get them from your account.
0
Thomas
Top achievements
Rank 1
answered on 06 May 2013, 06:29 PM
Hi Chavdar,
I would like to know how you tested these expressions to get the values you describe. I've previously tried everything that you have in your reply. ReportItem.DataObject.MyProperty fails with an error message in the report stating that MyProperty is not defined in the current context. The reason that it fails is because ReportItem.DataObject refers to the Table object data source and not the current item where MyProperty is defined. What I assume you are referring to is the binding for a detail text field in which case you are at the correct level in the object graph to retrieve the property value using either expression. This is not what I have asked for in my question. So my statement, in my context, is correct. The ListBoundReport you mention is a very simple report and does not have any dynamic row or column grouping so cannot be used to test what was asked.
As to the simple type as a data source statement, you pretty much just repeated what I had stated previously. Your solution is incorrect for the current context when using collections of complex types. I have tried your proposed expression already and the data object is not correct.
Using your expression of "=ReportItem.Report.DataSource.MyMethod(ReportItem.DataObject)" and doing GetType().ToString() on the passed object gives the following:
"Telerik.Reporting.Processing.Data.DataMember"
Why is your advice to use a user function instead of an instance method on the report data source? The report data source is the only object that has any knowledge of the data used to construct the report.
As to your mention of the expression or method not working, I never said it didn't work. I said the object passed was not the current list/table item data context. The method parameter type is System.Object. The method is called properly and I can check the passed values. There is no error when running the report so there is nothing to send you.
There is nothing fancy about the report layout. The report has a DetailSection. The detail section contains a List. The List contains a Panel that is used as a container for the repeating data. The List data source is a collection of objects from the report data source similar to List.DataSource = Report.DataSource.MyEntities.
DetailSection
List
Panel
TextBox1
TextBox2
The expressions in question are used to define the row and column groupings for the List. Below is an example using a simple expression that uses the Fields.MyProperty value to uniquely identify the current list item data context. This only works if the value of MyProperty is unique in the collection. The actual expressions are dynamically generated so they can be strongly typed.
var rowGroup = new TableGroup { Name = "MyGroupName" };
rowGroup.Groupings.Add(new Grouping("= ReportItem.Report.DataSource.MyMethod(Fields.MyProperty) / ReportItem.Report.DataSource.MyEntities.Count"));
lstDetailData.RowGroups.Add(rowGroup);
What I ended up doing, as mentioned previously, is pass a delimited string of values that can uniquely identify the object. So the parameter part of the expression is similar to "Fields.MyProperty1 + ',' + Fields.MyProperty2". The delimited string is split and the values cast to the proper data type then used as needed. As stated this does work to accomplish the needed results but is not as clean as just passing the current data object and acting upon it.
Cheers,
Tom
I would like to know how you tested these expressions to get the values you describe. I've previously tried everything that you have in your reply. ReportItem.DataObject.MyProperty fails with an error message in the report stating that MyProperty is not defined in the current context. The reason that it fails is because ReportItem.DataObject refers to the Table object data source and not the current item where MyProperty is defined. What I assume you are referring to is the binding for a detail text field in which case you are at the correct level in the object graph to retrieve the property value using either expression. This is not what I have asked for in my question. So my statement, in my context, is correct. The ListBoundReport you mention is a very simple report and does not have any dynamic row or column grouping so cannot be used to test what was asked.
As to the simple type as a data source statement, you pretty much just repeated what I had stated previously. Your solution is incorrect for the current context when using collections of complex types. I have tried your proposed expression already and the data object is not correct.
Using your expression of "=ReportItem.Report.DataSource.MyMethod(ReportItem.DataObject)" and doing GetType().ToString() on the passed object gives the following:
"Telerik.Reporting.Processing.Data.DataMember"
Why is your advice to use a user function instead of an instance method on the report data source? The report data source is the only object that has any knowledge of the data used to construct the report.
As to your mention of the expression or method not working, I never said it didn't work. I said the object passed was not the current list/table item data context. The method parameter type is System.Object. The method is called properly and I can check the passed values. There is no error when running the report so there is nothing to send you.
There is nothing fancy about the report layout. The report has a DetailSection. The detail section contains a List. The List contains a Panel that is used as a container for the repeating data. The List data source is a collection of objects from the report data source similar to List.DataSource = Report.DataSource.MyEntities.
DetailSection
List
Panel
TextBox1
TextBox2
The expressions in question are used to define the row and column groupings for the List. Below is an example using a simple expression that uses the Fields.MyProperty value to uniquely identify the current list item data context. This only works if the value of MyProperty is unique in the collection. The actual expressions are dynamically generated so they can be strongly typed.
var rowGroup = new TableGroup { Name = "MyGroupName" };
rowGroup.Groupings.Add(new Grouping("= ReportItem.Report.DataSource.MyMethod(Fields.MyProperty) / ReportItem.Report.DataSource.MyEntities.Count"));
lstDetailData.RowGroups.Add(rowGroup);
What I ended up doing, as mentioned previously, is pass a delimited string of values that can uniquely identify the object. So the parameter part of the expression is similar to "Fields.MyProperty1 + ',' + Fields.MyProperty2". The delimited string is split and the values cast to the proper data type then used as needed. As stated this does work to accomplish the needed results but is not as clean as just passing the current data object and acting upon it.
Cheers,
Tom
0
Hello Thomas,
You can find attached a sample project illustrating the suggested by my colleague usage of the ReportItem.DataObject and specifically ReportItem.DataObject.RawData giving the current bound object.
We will appreciate if you share with us your code how the List item is created or/and grouped dynamically, and what object is used as data source, so we can check for other approaches.
Kind regards,
Stef
the Telerik team
You can find attached a sample project illustrating the suggested by my colleague usage of the ReportItem.DataObject and specifically ReportItem.DataObject.RawData giving the current bound object.
We will appreciate if you share with us your code how the List item is created or/and grouped dynamically, and what object is used as data source, so we can check for other approaches.
Kind regards,
Stef
the Telerik team
Have you tried the new visualization options in Telerik Reporting Q1 2013? You can get them from your account.
0
Thomas
Top achievements
Rank 1
answered on 10 May 2013, 04:09 PM
Hi Stef,
The sample provided uses a collection as the report data source. I use an object data source that has a property that is a collection of objects. The collection is used as the data source of a List on the report. I've explained what I wanted to do but obviously not well enough because you are confused as to what I am asking. I have no trouble getting the report data source which is what your suggestion of ReportItem.DataObject.RawData gives. I think you guys are trying to solve something that I am not asking for.
My original question was if there is a way to get the current List item data source, using an expression similar to the Fields.Item syntax but for a collection of complex objects (not System.String or System.Int32). The current list item data source should be one of the objects contained in the collection that is used as the List data source.
Cheers,
Tom
The sample provided uses a collection as the report data source. I use an object data source that has a property that is a collection of objects. The collection is used as the data source of a List on the report. I've explained what I wanted to do but obviously not well enough because you are confused as to what I am asking. I have no trouble getting the report data source which is what your suggestion of ReportItem.DataObject.RawData gives. I think you guys are trying to solve something that I am not asking for.
My original question was if there is a way to get the current List item data source, using an expression similar to the Fields.Item syntax but for a collection of complex objects (not System.String or System.Int32). The current list item data source should be one of the objects contained in the collection that is used as the List data source.
Cheers,
Tom
0
Hi,
It wasn't very clear from the first posts where exactly you are expecting to get the current list item. If we have understood you correctly you are using this expression in a grouping expression. If this is the case then you are correct and you can reference the properties of the complex object only through =Fields.MyProperty expressions. Still, you can use the suggested solution for the report items which are inside the List item.
Greetings,
Chavdar
the Telerik team
It wasn't very clear from the first posts where exactly you are expecting to get the current list item. If we have understood you correctly you are using this expression in a grouping expression. If this is the case then you are correct and you can reference the properties of the complex object only through =Fields.MyProperty expressions. Still, you can use the suggested solution for the report items which are inside the List item.
Greetings,
Chavdar
the Telerik team
Have you tried the new visualization options in Telerik Reporting Q1 2013? You can get them from your account.