A PrintDocument may be data bound to populate the control with data by fetching it from an underlying data source. The main property that facilitates data binding is the DataBinding property in RenderObject, of the type C1DataBinding, which allows to specify the data source for data shown by the render object.
The document can contain the database schema (represented by the class C1DataSchema, and include the data base connection info, SQL queries etc.) inside. The C1DataBinding objects within the document can reference properties of that schema. If all data-bound objects in a document reference only the properties of the C1DataSchema of the document itself, the document becomes "data reflowable". That is, the document can be regenerated independently of the program used to create it, with data completely updated from the database. Also, the C1DataBinding object may reference existing data sources (DataTable and so on) which were created on the form or elsewhere in the program that created that PrintDocument.
When a render object is created, the data binding for it is not created initially. It is created when the DataBinding property is referenced in the user code. This is depicted in the code snippet below:
C# |
Copy Code
|
---|---|
RenderText rt = new RenderText(); // ... if (rt.DataBinding != null) { MessageBox.Show("Data binding defined."); } |
The condition in the previous code will always evaluate to True. Thus, if you only want to check whether data binding exists on a particular render object, you should use the DataBindingDefined property instead:
C# |
Copy Code
|
---|---|
RenderText rt = new RenderText(); // ... if (rt.DataBindingDefined) { MessageBox.Show("Data binding defined."); } |
This is similar to the Handle and IsHandleCreated properties of the WinForms Control class.
During document generation, the RenderObjectsList collection is created. In such a case, three different situations are possible:
A RenderTable is used to represent a data table in PrintDocument. It can be data bound using the DataBinding property in the TableVectorGroup, which is the base class for table row and column groups.
Please note that it is not just groups of rows, but also groups of columns that can be bound to data. That is, a table can grow not only downwards, but also sideways. The group hierarchy in data-bound tables is based on the hierarchy of the TableVectorGroup objects, and this is depicted in the code below:
C# |
Copy Code
|
---|---|
// make the document: C1PrintDocument doc = new C1PrintDocument(); doc.Style.FontName = "Verdana"; doc.Style.FontSize = 12; // document title: doc.Body.Children.Add(new RenderText("List of Customer orders, customers are listed vertically, orders horizontally")); doc.Body.Children.Add(new RenderEmpty("5mm")); // empty space after title // outer render table will loop through master records: RenderTable rt = new RenderTable(); rt.Style.GridLines.All = LineDef.Default; // group master by Id. // Each master group will contain 2 rows: // - header row with customer Id and Name; // - detail row, with customer's OrderId's IN A ROW (spread horizontally in a nested table). TableVectorGroup gMaster = rt.RowGroups[0, 2]; gMaster.DataBinding.DataSource = customerOrders; gMaster.DataBinding.Grouping.Expressions.Add("Fields!Id.Value"); // 1st row: rt.Cells[0, 0].Text = "Id: [Fields!Id.Value]"; rt.Cells[0, 1].Text = "Name: [Fields!Name.Value]"; // 2nd row: a nested table: RenderTable rt2 = new RenderTable(); rt2.Style.BackColor = Colors.BlanchedAlmond; rt2.Style.GridLines.Vert = new LineDef("1pt", Colors.DarkOliveGreen); rt2.Style.FontSize = rt.Style.FontSize - 2; rt2.CellStyle.Padding.All = "1mm"; TableVectorGroup dDetail = rt2.ColGroups[1, 1]; dDetail.DataBinding.DataSource = customerOrders; rt2.Cells[0, 0].Text = "[Fields!Name.Value]'s orders: "; rt2.Cells[0, 1].Text = "[Fields!OrderId.Value]"; // auto-size the first column (with customer's name), spread the rest: rt2.Cols[0].SizingMode = TableSizingModeEnum.Auto; rt.Cells[1, 0].RenderObject = rt2; rt.Cells[1, 0].SpanCols = 2; doc.Body.Children.Add(rt); this.c1DocumentViewer1.Document = doc.FixedDocumentSequence; |
As you can observe from the code, the C1DataBinding class provides the Grouping property to get the C1.C1Preview.DataBinding.Grouping object that determines how data retrieved by the current data binding is grouped. The Grouping class provides a set of expressions that determine the grouping of data in a data-bound object in a PrintDocument. It is the Expressions property in the Grouping class that gets the collection of expressions defining data grouping. When the document is generated, a new group starts if at least one expression in this collection evaluates to a different value. The C1DataSchema class provides the Aggregates property to get the collection of named Aggregate objects defined in the current data schema.
The Aggregate(string name, string expressionText, C1.C1Preview.DataBinding.C1DataBinding dataBinding, C1.C1Preview.DataBinding.RunningEnum running, C1.C1Preview.DataBinding.AggregateFuncEnum func) method overload in the Aggregates class initializes a new instance of the class and assigns the name, expression, data binding, scope and function of the aggregate.
The overload method passes the following parameters: