By Ivan George Borges - 10/9/2006
Hya.I am trying to bind an XtraReport label to a BO field. Does our BO implements the IList, ITypedList or IBindingList interface? That's what the XtraReport asks me in the help file. I get an error after I set the report DataSource to the BO : Private Sub RelEmpresasToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RelEmpresasToolStripMenuItem.ClickDim Report As New rptEmpresas()Dim loEmpresas As New ProFilmeNET_BOL.boEmpresas()loEmpresas.FillDataTable( "Select * from Empresas")Report.DataSource = loEmpresas Report.lblNome.DataBindings.Add( "Text", loEmpresas, "emp_Descr")Report.ShowPreviewDialog() End SubAny word of advice to direct me in the right direction will be appreciated. Thanks in advance.
|
By Trent L. Taylor - 10/9/2006
That is what the BusinessBindingSource control does for you. If you drop (or create a variable) on you form, you can the set the BusinessObject property to any business object. This basically wraps the BO and provides the IBindingList interface as well.
|
By Ivan George Borges - 10/10/2006
Thanks Trent.I'm in a client right now, I will try it later.
|
By Ivan George Borges - 10/10/2006
I know it sounds stupid. But I'm extremely happy I put a simple report to work!Thanks a lot Trent.
|
By StrataFrame Team - 10/10/2006
Glad you got it working, Ivan
|
By Paul Chase - 10/13/2006
Ivan,I was able to trick the Xtra Report into allowing you to drop a BusBinding Source and Bus object onto it. first create a base class report that implements IContainer. I still need to figure a few things out to make it better but below is what I have so far and seems to work. The Preview won't work but you can bind all the fields etc. But to be honest i am wondering if I even wnat to use BO's for the reports as it seems like most reports i have are base on query's with joins. But here is what I did maybe it will be helpful Public Class XtraReportBase Implements MicroFour.StrataFrame.UI.Windows.Forms.IContainerControl 'Add This Line Public Sub New() ' This call is required by the Windows Form Designer. InitializeComponent() ' Add any initialization after the InitializeComponent() call.End SubPublic Sub AddBusinessObject(ByVal BusinessObject As MicroFour.StrataFrame.Business.BusinessLayerBase) Implements MicroFour.StrataFrame.UI.Windows.Forms.IContainerControl.AddBusinessObject End Sub Public Sub AddObjectToInitOnLoad(ByVal ObjectToInit As MicroFour.StrataFrame.UI.IInitOnFormLoad) Implements MicroFour.StrataFrame.UI.Windows.Forms.IContainerControl.AddObjectToInitOnLoadEnd SubPublic Sub AddObjectToPreInitOnLoad(ByVal ObjectToPreInit As MicroFour.StrataFrame.UI.IPreInitOnFormLoad) Implements MicroFour.StrataFrame.UI.Windows.Forms.IContainerControl.AddObjectToPreInitOnLoadEnd SubPublic Sub RemoveBusinessObject(ByVal BusinessObject As MicroFour.StrataFrame.Business.BusinessLayerBase) Implements MicroFour.StrataFrame.UI.Windows.Forms.IContainerControl.RemoveBusinessObjectEnd SubEnd ClassNow go into the designer.vb file of the base report and change Friend WithEvents Detail As DevExpress.XtraReports.UI.DetailBandFriend WithEvents PageHeader As DevExpress.XtraReports.UI.PageHeaderBandFriend WithEvents PageFooter As DevExpress.XtraReports.UI.PageFooterBandto Protected WithEvents Detail As DevExpress.XtraReports.UI.DetailBandProtected WithEvents PageHeader As DevExpress.XtraReports.UI.PageHeaderBandProtected WithEvents PageFooter As DevExpress.XtraReports.UI.PageFooterBand Next create a new class that looks like below Public Class InheritedReport Inherits ReportBase.XtraReportBase ' The base class from above Public Sub New()InitializeComponent() End SubPrivate Sub InitializeComponent()End SubEnd ClassRebuild and you should be able to get into the designer of your new subclassd report Drop a business binding source and bus object on the form set the data source of the report to be the business binding source. The type editor of the business binding source will not work so you need to set it manually in the init component. Maybe this can figured out Public Class InheritedReportInherits ReportBase.XtraReportBaseFriend WithEvents XrLabel1 As DevExpress.XtraReports.UI.XRLabelFriend WithEvents BusinessBindingSource1 As MicroFour.StrataFrame.Business.BusinessBindingSourceFriend WithEvents BusinessObject11 As TEstBO.BusinessObject1Private components As System.ComponentModel.IContainerPublic Sub New(Lcname as String)InitializeComponent() I also added the fill method here ? works Me.BusinessObject11.FillByName(LcName)End Sub Private Sub InitializeComponent()Me.components = New System.ComponentModel.ContainerMe.XrLabel1 = New DevExpress.XtraReports.UI.XRLabelMe.BusinessBindingSource1 = New MicroFour.StrataFrame.Business.BusinessBindingSource(Me.components)Me.BusinessObject11 = New TEstBO.BusinessObject1(Me.components)CType(Me, System.ComponentModel.ISupportInitialize).BeginInit()''Detail'Me.Detail.Controls.AddRange(New DevExpress.XtraReports.UI.XRControl() {Me.XrLabel1})''XrLabel1'Me.XrLabel1.Location = New System.Drawing.Point(33, 8)Me.XrLabel1.Name = "XrLabel1"Me.XrLabel1.Padding = New DevExpress.XtraPrinting.PaddingInfo(2, 2, 0, 0, 100.0!)Me.XrLabel1.Size = New System.Drawing.Size(100, 25)Me.XrLabel1.Text = "XrLabel1"''BusinessBindingSource1'Me.BusinessBindingSource1.ParentForm = Nothing'Manually add Line BelowMe.BusinessBindingSource1.BusinessObject = Me.BusinessObject11''BusinessObject11'Me.BusinessObject11.ParentContainer = MeMe.BusinessObject11.SynchronizingObject = NothingCType(Me, System.ComponentModel.ISupportInitialize).EndInit()End SubEnd Class Now to call the report... Dim rpt As New TestAppReports.InheritedReport("TEST")rpt.ShowPreview()
|
By Ivan George Borges - 10/13/2006
Hi Paul.Thanks for your help! I will study your code. I have created an XtraReport abstract class, and in the inherited ones I've being writing code to bind the controls at runtime. I've been able to run the reports using the BOs, but I've been creating them at runtime. I'm not binding the report controls at design time. So, I use the BOs to populate the information I need, then add them to a DataSet, working with the results there. So far, I haven't created very complex reports, yesterday I managed to make a Master-Detail report to work using the BOs in this way. But you are right, I wonder what the best practice will be when a more complex situation arrives. As usual, I think I will let Trent, Ben and Steve worry for me.  I bet they are gonna jump in and say something.
|
By Paul Chase - 10/13/2006
Ivan,I have been struggling with the concept of how I want to deal with Reports and Data Access for the last few days and I can't seem to decide how best to implement it. I guess it would be nicer to have all the data access come from a bus object library. But at the same time with joined queries for reporting it makes it a bit trickier. I guess you would have to create a view and base a bo off the view. At the same time it is simple enough to create the typed DS right in the report. but you need watch connection strings etc. I guess it really doesnt matter.
|
By Trent L. Taylor - 10/13/2006
Well if it were me I would not venture too far from the business objects. You can create any type of JOIN query from within a BO to return any fields that you want. You can create a view, as you mentioned, to pull back all of the fields you want in a flat format. If you need to create custom fields or a BO that supports a special DDT layout and then your FillDataTable(...) method pulls data using the inner join, you can. When you start dealing with typed data sets you are heading for frustrations the first time you want to make a change. There are a lot of different ways to "skin the cat" so to speak...but you also want to make sure that you are not painting yourself into a corner down the road.Any of these options, including the typed data set, will work. But when you start pulling connection strings and talking directly to the data you are breaking encapsulation so if some day you want to change your back end...including the Middle Tier Enterprise Server, your reports will break. If you work inside the confines of the business object you can change your backend database or connect to the Enterprise Server interchangeably without having to change this code. Note: Any custom connection you make outside of the logic of the framework will prevent the data access layer from being interchangable without having dramatic side-effects within your application...this includes the Middle Tier Enterprise Server that will be released by the end of the year.
|
By Ivan George Borges - 10/13/2006
Hi guys.Trent L. Taylor (10/13/2006) Well if it were me I would not venture too far from the business objects. This is exactly what I keep in mind. I realize there's a whole attention built inside the BOs, and for a start I want to take advantage of not having to worry about it. And then, there's the back end, and the Middle Tier. I will stick to the BOs. You can create any type of JOIN query from within a BO to return any fields that you want. You can create a view, as you mentioned, to pull back all of the fields you want in a flat format. If you need to create custom fields or a BO that supports a special DDT layout and then your FillDataTable(...) method pulls data using the inner join, you can. This is where I need to get proficiency at. But seeing you say it is possible, is already a good incentive. So, Paul, I think we will be safer under the wings of the BOs. Guess we just have to find our way in it.
|
By Paul Chase - 10/13/2006
Thanks Trent that helps somewhat and answers alot of the issues I have been knocking around. I defiinatly would rather use the BO's but was not sure on the joined query's .One of the issues I have is that I HATE doing reports.. When I first started in IT that is all I did for many years. I want to be able to set up the query and any grouping on the report and have one of the girls do the tedious pretty work. This does require that the fields be bound to something at design time. I will probably have specific questions on how to set up a bo to support a joined query and provide the strongly typed fileds required to make design time report binding possible. I just havent had a chance to try it so don't know. Paul
|
By StrataFrame Team - 10/13/2006
Well, Paul, when you get those specific questions, send them to us and we'll certainly try to get them answered.
|
By Paul Chase - 10/13/2006
Trent,Below is query that I had just had to create for our accounting department. I have no idea how I would be able to use business objects to create a design time datasource for a report based on this query. I have to create a stored proc(parameters) or query a view of the joined data, or I use the sql data adapter method on the report and generate the table which I don't like. For reporting you do not need to be able to insert update or delete which is the reason that business objects are what they are. However with a report you do not need that funtionality. Would it be possible to create another type of object? A stripped down business object call it a report object that is strongly typed based upon the fields returned from the select query? This would provide for a read only view of data that could be bound in reports grids etc. Maybe i am missing something but I just cannot seem to get my head around this so please be patient if I am in left field somewhere but the light is just not coming on SELECT ECOApplyTo.CUSTNMBR as [Customer Id], RM00101.CUSTNAME as [Customer Name], RM00201 .CLASDSCR as [Office], RM20101.CHEKNMBR as [Check Number], ECOApplyTo.DATE1 as [Applied Date],ECOApplyTo.APFRDCNM as [Audit Trail], ECOApplyTo .ActualApplyToAmount, ECOApplyTo.APTODCDT as [Invoice Date], RM00101.CUSTCLAS,RM20101 .ORTRXAMT as [Original Invoice Amount],ECOApplyTo.APPTOAMT as [Amount Applied], CAST (ECOApplyTo.DATE1 - ECOApplyTo.APTODCDT AS int) AS Age, ALM_RM20201X.DOCNUMBR as [Invoice Number], ALM_RM20201X.CURTRXAM as [Current Invoice Balance],( case when CAST(ECOApplyTo.DATE1 - ECOApplyTo.APTODCDT AS int) > 50 then ActualApplyToAmount else 0 end) as inEligable ,( case when CAST(ECOApplyTo.DATE1 - ECOApplyTo.APTODCDT AS int) < 51 then ActualApplyToAmount else 0 end) as Eligable ,DateAdd (day, -1 * datepart(dw, Date1), Date1 ) as weekFROM RM00101 INNER JOINECOApplyTo ON RM00101.CUSTNMBR = ECOApplyTo.CUSTNMBR INNER JOINRM00201 ON RM00101.CUSTCLAS = RM00201.CLASSID INNER JOINRM20101 ON ECOApplyTo.APFRDCNM = RM20101.DOCNUMBR INNER JOINALM_RM20201X ON ECOAPPLYTO.APTODCNM = ALM_RM20201X.DOCNUMBRWHERE RM20101.RMDTYPAL = 9 and date1>= @FromDate and date1 <=@ThruDate and Substring(CUSTCLAS,1,3) = @OfficeIDorder by CLASDSCR,week,[Customer Id]
|
By StrataFrame Team - 10/13/2006
You can done one of a few things, Paul:1) Create a fake table in some temp database in SQL Server that has the same structure as the results of your join and build the business object off of that. Then, you will automatically have your strong-typed fields becuase the BOMapper will be able to "see" the object that has the structure that you want. 2) Create a fake table in some temp profile in the DDT that has the same structure as the results of your join... same thing as the one above... Once you build the business object through the BOMapper, it becomes a strong-typed design-time data source for your report. So, no matter what the crazy structure of your report, you can always create a business object that matches the structure by creating "dummy" structure sources in either the DDT or SQL Server.
|
By Ivan George Borges - 10/13/2006
Sorry for the stupid question Ben.I got the idea for the dummy table in the DDT, a fake Database there, and then map the BO. Then, after instanciating the BO, I would just create a fill method with Paul's sql statement and be happy forever?
|
By StrataFrame Team - 10/13/2006
Hehe, no questions are stupid, that's for sure... and yes, you have it right.
|
By Ivan George Borges - 10/13/2006
Hey, Paul.I did the changes you mentioned before to get the BO dropped into the designer. It worked fine!!! But have you tried the "Preview" ? I get an error message like this: Serialization Error 81: The type or namespace name 'tboTeste' does not exist in the namespace 'ProFilmeNET_BOL' (are you missing an assembly reference?)
|
By Paul Chase - 10/13/2006
Yeah I havent figured out how to make that work.. Dont hit HTML it will crash visual studio
|
By Ivan George Borges - 10/14/2006
too late ...
|
By Paul Chase - 10/16/2006
Ben,I understand what you are saying about using a temp table to allow me to generate the fields for strong typing to be able to use the report designer at designtime. That should work ok but I would like to create a seperate report object type that would use the strataframe DAL but be generated using the schema returned from a select statement. This should give me the strong typing I would like as well as allow me some flexibility in having it able to work with Xtra Reports. I guess I am just trying to make the reporting process seem a bit more straight foward and maybe I am complicating it more than it needs to be but for some reason reporting in .net seems to be a pain in the neck. Anyways if worse come to worse I know that I can do as you suggested and it will work. Paul
|
By Tim Dol - 10/16/2006
Hi Ivan,I'm also having problems dropping a BO onto the report designer so I can pick and choose the fields I want. I was able to drop the BusinessBindingSource but got an error trying to assign a BO. How did you get this working? Thanks, Tim
|
By Paul Chase - 10/16/2006
Tim you need to manually assign the bus object to the binding source in the code behind of the report.
|
|