Hi,
The problem we are having I believe is very similar to this:
http://ko.infragistics.com/community/forums/t/58897.aspx
But, we have tried what is suggested there (static function) and we have not been able to fix our problem.
We are simply trying to create an Object Data Source. But when we try to select the class that will return the data, we cannot find ANY properties or methods to select.
We are using v14.1 of Infragistics tools.
Here is a code snippet showing some of the ReportDataViewModel class we are trying to use to create the data source:
public class ReportDataViewModel : DataViewModel { Frequency _frequency; int? _index; Report _report; public Report Report { get { return _report; } } public Forecast Forecast { get { return _report.Forecast; } } public ForecastViewModel ForecastVM { get { return ViewModelFactory.GetForecastViewModel(_report); } } public override string Label { get { if (_frequency == Forecast.CycleFrequency || _index == null) return "All"; else return Forecast.CyclePeriods[(int)_index].Label; } } DataView _dataView; public override DataView DataView { get { var ind = _index; if (Report is VarianceReport) ind = MainWindowViewModel.MainWindowVM.SelectedActualIndex; if (_dataView == null) using (new WaitCursor()) _dataView = _report[_frequency, ind, true]; return _dataView; } } public static IEnumerable<ReportDataRow> ReportDataSource(DataView theView) { foreach (DataRowView rowView in theView) { DataRow row = rowView.Row; yield return new ReportDataRow { ParentRowNum = row["ParentRowNum"] is System.DBNull ? 0 : (int)row["ParentRowNum"], RowNum = row["RowNum"] is System.DBNull ? 0 : (long)row["RowNum"], Name = row["Name"].ToString(), Id = row["Id"] is System.DBNull ? 0 : (int)row["Id"], NodeType = row["NodeType"] is System.DBNull ? 30000 : (int)row["NodeType"], NodePath = (string)row["NodePath"], RecordNodeId = row["RecordNodeId"] is System.DBNull ? 0 : (int)row["RecordNodeId"], BudgetDataType = row["BudgetDataType"] is System.DBNull ? 0 : (int)row["BudgetDataType"], BudgetDataNodeId = row["BudgetDataNodeId"] is System.DBNull ? 0 : (int)row["BudgetDataNodeId"], ResultNodeId = row["ResultNodeId"] is System.DBNull ? 0 : (int)row["ResultNodeId"], Opening = row[10] is System.DBNull ? 0 : (decimal)row[10], Period0 = row[11] is System.DBNull ? 0 : (decimal)row[11], Period1 = row[12] is System.DBNull ? 0 : (decimal)row[12], Period2 = row[13] is System.DBNull ? 0 : (decimal)row[13], Period3 = row[14] is System.DBNull ? 0 : (decimal)row[14], Period4 = row[15] is System.DBNull ? 0 : (decimal)row[15], Period5 = row[16] is System.DBNull ? 0 : (decimal)row[16], Period6 = row[17] is System.DBNull ? 0 : (decimal)row[17], Period7 = row[18] is System.DBNull ? 0 : (decimal)row[18], Period8 = row[19] is System.DBNull ? 0 : (decimal)row[19], Period9 = row[20] is System.DBNull ? 0 : (decimal)row[20], Period10 = row[21] is System.DBNull ? 0 : (decimal)row[21], Period11 = row[22] is System.DBNull ? 0 : (decimal)row[22], }; } } public string Format { get { return Forecast.Format + ";-"; } }
Hi Forecast Five,
The Data Source Configuration Wizard can only handle methods that take in generic arguments like int, string, decimal, etc. It doesn't handle complex types. When you try to create a data source from a method that takes arguments, the wizard will ask you for what arguments you want to pass to the method. The wizard does not have the capability to create a complex type to pass to this argument so we only support generics.
I think you'll need to go about this differently. Rather than trying to pass a DataView directly to the method, your method should take in an ID or something that the method can then use to identify which DataView to use and this DataView should be stored somewhere the method can access it from.
Thanks for the prompt reply Rob, but we think something else is going on.
We took what you said on board, and we create a simple datasource.
We created a new static class like this:
namespace Forecast5.ViewModel { public static class ReportDataSource { public static IEnumerable<int> ReportData() { List<int> iList = new List<int>(); iList.Add(2); iList.Add(3); iList.Add(5); iList.Add(7); return iList; } } }
But when we start the wizard and select this new class...:
Your method must return an IEnumerable of a complex type. There are no public properties in an integer so the report can't create columns from that. In my last update I only mentioned that the arguments you pass into the method must be generic types. This should work:
public static IEnumerable<ComplexObject> ReportData(int viewId){ return new List<ComplexObject> { new ComplexObject() { prop1 = 0 }, new ComplexObject() { prop1 = 1 }, };}
public class ComplexObject{ public int prop1 { get; set; }}
Thanks Rob.
We are now able to see the function and create the datasource.
We do have one more question... Is it possible to create hierarchical SQL based data sources?
We used to have a dataview with a relationship defined. .This was then bound to a datagrid and (hence the relationship was defined) the grid showed the data correctly.
This did not give us enough flexibility when it came to reports though.
We are now trying to get the data into a report. Creating this relationship in classes is proving troublesome.
Is there a way we can get the report to see this relationship from the dataview at design time?
Can we create the report using the object datasource and then just change the datasource at runtime to be the dataview with the relationship?
Thanks
Forecast5 Developer
It is possible to change the data source at runtime so yes, you can have the designer deal with one set of data while at runtime you can have it load up different data. Check out the following documentation: http://help.infragistics.com/doc/Reporting/2014.2/CLR4.0/?page=How_to_Change_the_Data_Sources_at_Run_Time_Using_IReportDataSourceProvider.html
Hi Rafael,
Keep in mind that the SQL Data Source requires a connection string so generally your table information will be stored inside a database. Having the DataView loaded in your actual application won't work as you can't pass it directly to the report. So if your table is stored in a SQL database you can use the SQL Data Source. In which cause, you can just hook up the report to the database at design time and it should let you see the hierarchy.
Another thing to keep in mind is that you can't set a report to use an Object Data Source at design time and then change it to use a SQL Data Source at run time. They can't be swapped. You can, however, specify a SQL Data Source at design time and at runtime switch to an Object Data Source. The IReportDataSourceProvider is expecting an IEnumerable as a return value so having a SQL Data Source setup at design time, along with an IReportDataSourceProvider, effectively allows you to switch to an object datasource. It does not work the other way though.
I'm not really sure what the best option for you is. I'd really recommend just using an object datasource wherever possible. If you have a DataView in memory already and your not downloading it from a SQL database then I would just convert it to a class and use the IReportDataSourceProvider to return the new class data. However, the report must know the schema for the data at design time so dynamic data where you don't know what the columns are isn't going to work. If you are downloading it from SQL then don't bother with changing the datasource at runtime, just setup the SQL stuff at design time. If you need to change connection strings we have documentation for that:http://help.infragistics.com/doc/Reporting/2014.2/CLR4.0/?page=How%20to%20Change%20the%20Connection%20String%20at%20Run-Time.html
Hi Rob,
The problem that we have is that we do not see the hierarchical structure when we are at design time, so we cannot set it up correctly.
Hence the question, how do we set up and SQL Hierarchical data source.
The DataView has a couple of columns defined (RowNum and ParentRowNum) and the relationship is defined against these two columns.
The idea was to setup a SQL Hierarchical data source for design time and then have swap it out at runtime with the data view.
From what I can understand on what you are saying now, is that we should be able to use the dataview now as the hierarchical data source has been set up?
[EDIT: As you said, we need to make sure that the schema is the same. But how do we make a SQL Data Source look the same as an object data source?]
Rafael
Why not just configure the report to use the SQL data source at design time? You can bind the report to a SQL data source as long as you have the connection string. You can even specify a custom query in order to return the data however you like.
http://help.infragistics.com/doc/Reporting/2014.2/CLR4.0/?page=How_to_Bind_a_Report_to_a_SQL_Data_Source.html
As far as changing from an object based data source to a SQL one at runtime, yes this is possible but not in the way you are thinking. You still need to use that IReportDataSourceProvider in order to change the data source at runtime. What you do inside the provider is up to you. You can pull data from a SQL datasource and return that or you can continue using an object datasource. The only thing that matters is that the data returned from the provider needs to have the same schema as what the report was setup for.
Yes, we have seen that... The questions we have are around the SQL Data Source and whether we can have a hierarchical SQL data source.
We have a table that has a parent child relationship [many levels deep], and we want to know how we can use this to bind to the report...
Or do we need to turn it into an object based data source?
If we design the report using an Object Based data source, can we change it at run-time to a SQL Based one?
thanks