First of all, we must thank and Salute Waxman Zhang:
Http://waxdoll.cnblogs.com/archive/2006/02/25/337713.html
2. Microsoft Gotreportviewer Official case:
http://www.gotreportviewer.com/(about 20 or so, very detailed.) Sometimes it doesn't.)
)
The previous time, did the RDLC report, mainly is three block function:
1, extract data from the DataGrid, and then create the corresponding RDLC report file, to take advantage of the ReportViewer class of printing and typesetting function (which made a general function of extracting data, can extract any control data; As long as the mosaic into a DataTable this mesh lattice is good)
2, to a simple rdlc template to provide the table header font format and table internal data and other styles related information, and then use the data extracted from the DataGrid to populate the report
3, made a TreeView, very simple; depending on the name of the report file, toggle item on the left tree to load different reports and display the data. With a little bit of reflective knowledge.
First step: Generate the corresponding classes and namespaces according to the report Definition Language (RDL).
1, to
http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition/
Download reportdefinition2010.xsd.
Note: There is a time difference between reportdefinition and Visual Studio, with 2005 and 2008 versions on the official website. Version 2005, VS2008 later support, 2008 version, VS2010 later support. Version 2010, to VS2012
Support later. Mine is VS2010, using the 2008 version.
2, find the XML Schema Definition Tool (Xsd.exe), the Windows operating system will bring it. For more detail,please refer to:
https://msdn.microsoft.com/en-us/library/x6c1kb0s (v=vs.110). aspx
Below is my CMD in administator mode:
C:\Program Files (x86) \microsoft Sdks\windows\v7.0a\bin\x64>xsd
/c/n:rdlc
/out:c:\users\admin\desktop\rdlcreportresearch
C:\Users\admin\Desktop\RDLCReportResearch\ReportDefinition.xsd
It's finished, it's like this.
usingSystem.Xml.Serialization; /// <remarks/>[System.CodeDom.Compiler.GeneratedCodeAttribute ("xsd","2.0.50727.3038")] [System.SerializableAttribute ()] [System.Diagnostics.DebuggerStepThroughAttribute ()] [System.componentmode L.designercategoryattribute ("Code")] [System.Xml.Serialization.XmlTypeAttribute (Anonymoustype=true, namespace="http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")] [System.Xml.Serialization.XmlRootAttribute (Namespace="http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition", isnullable=false)] Public Partial classReport {Private Object[] Itemsfield; Privateitemschoicetype80[] Itemselementnamefield; Privatesystem.xml.xmlattribute[] Anyattrfield; /// <remarks/>[System.Xml.Serialization.XmlAnyElementAttribute ()] [System.Xml.Serialization.XmlElementAttribute ("Author",typeof(string)] [System.Xml.Serialization.XmlElementAttribute ("AutoRefresh",typeof(UINT)] [System.Xml.Serialization.XmlElementAttribute ("Body",typeof(BodyType))] [System.Xml.Serialization.XmlElementAttribute ("Classes",typeof(Classestype))] [System.Xml.Serialization.XmlElementAttribute ("Code",typeof(string)] [System.Xml.Serialization.XmlElementAttribute ("CodeModules",typeof(Codemodulestype))] [System.Xml.Serialization.XmlElementAttribute ("Consumecontainerwhitespace",typeof(BOOL))]
ReportDefinition.cs
Step Two: Create the Rdlcgenerator class and the Tablixrdlcgenerator class
Based on the downloaded report Definition Language (RDL) and a simple rdlc file created, it is easy to know which parts of the rdlc file are basically composed, and then the layers are created in a nested form.
The Tablix is the key data area, gotreportviewer the above example, Dynamicmatrix and dynamictable are done according to RDL2005, RDL2008 later, is a tablix:
/// table + matrix = Tablix /// Microsoft uses a Tablix to support table (table), Matrix, and List (list) of three report items /// integration of table and matrix functions
View Code
Step three: Extract data from the DataGrid
From the DataGrid, the cell width, data, Bindingpath, and headername are mostly taken. Now for DataGridColumn with DataTemplate do not know why did extract Bindingpath data, Datagridhyperlinkcolumn also do not take bindingpath. I hope someone will be helpful.
/// <summary> ///a DataGrid converter that extracts data sources from the DataGrid, as well as the headername, binding path, and ActualWidth/// </summary> /// <param name= "DataGrid" >Datgrid that contain data</param> /// <param name= "DT" >DataTable converted to DataGrid data source</param> /// <param name= "Headernames" >Datagridcolumn.header</param> /// <param name= "Bindingpaths" >DataGridBoundColumn.Binding.Path</param> Public Static voidDatagridadapter ( ThisDataGrid DataGrid, DataTable DT, list<string> Headernames, list<string> Bindingpaths, list<Double>widths) { //Remove DataGridColumn header,bingdingpath,actualwidth to prepare data for the construction RDLC fileheadernames.clear (); Bindingpaths.clear (); Widths. Clear (); for(intindex =0; Index < DataGrid.Columns.Count; index++) {Headernames.add (Datagrid.columns[index]. Header as string); Widths. ADD (Datagrid.columns[index]. ActualWidth); //string Tempbindingpath = ((Datagrid.columns[index] as Datagridboundcolumn). binding as binding). Path.path; stringTempbindingpath =Getdatagridcolumnbindingpath (Datagrid.columns[index]); Bindingpaths.add (Tempbindingpath); if(String.IsNullOrEmpty (tempbindingpath) = =false) dt. Columns.Add (Tempbindingpath,typeof(string)); } for(intRowIndex =0; RowIndex < DataGrid.Items.Count; rowindex++) { //To be displayed before the data is takenDataGridRow Rowcontainer =(DataGridRow) DataGrid.ItemContainerGenerator.ContainerFromIndex (RowIndex); //because of the peformance problem, Enablerowvirtualization is set to true to load only the data to be displayed//re-scroll, and then reuse these DataGridRow if(Rowcontainer = =NULL) {datagrid.updatelayout (); Datagrid.scrollintoview (Datagrid.items[rowindex]); Rowcontainer=(DataGridRow) DataGrid.ItemContainerGenerator.ContainerFromIndex (RowIndex); } if(Rowcontainer! =NULL) {Datagridcellspresenter presenter= datagridhelper.getvisualchild<datagridcellspresenter>(Rowcontainer); if(Presenter! =NULL) {DataRow Dr=dt. NewRow (); BOOLIslastrowallempty =true; for(intColumnIndex =0; ColumnIndex < Bindingpaths.count; columnindex++) {DataGridCell cell=(DataGridCell) presenter. Itemcontainergenerator.containerfromindex (columnindex); if(Cell! =NULL) { if(Cell. Content isTextBlock) { //Todo:datagridhyperlinkcolumn data not being takenDr[bindingpaths[columnindex]] = (cell. Content asTextBlock). Text; if(! String.IsNullOrEmpty (cell. Content asTextBlock). Text)) Islastrowallempty =false; } Else if(Cell. Content isCheckBox) { stringValue = ((cell. Content asCheckBox). IsChecked = =true) ?"is a":"No"; Dr[bindingpaths[columnindex]]=value; } Else if(Cell. Content isComboBox) {Dr[bindingpaths[columnindex]]= (cell. Content asComboBox). Text; if(! String.IsNullOrEmpty (cell. Content asComboBox). Text)) Islastrowallempty =false; } } } if(Datagrid.canuseraddrows && (RowIndex = = DataGrid.Items.Count-1)) { //if Canuseraddrows is set to true, only the last row of data is not empty (checkbox does not count as inside) to add data to the DataTable if(islastrowallempty) {Continue; }} dt. Rows.Add (DR); } } } }
extracting DataGrid Data
Fourth step: Populating the data
The key is to set the Localreport.reportpath and Localreport.datasources of the ReportViewer Class.
Not finished, to be continued (can not put all the source code, only write the key part, a little bit long code, in addition, although all I write code, but after all, is working with others, posted out is not a leak, the company opened what to do)
Dynamic report generation of RDLC reports