PrintDocument for WinForms | ComponentOne
PrintDocument Library / Data Binding
In This Topic
    Data Binding
    In This Topic

    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 re-flowable". 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.

    Data Binding in Render Objects

    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:

    Working with Data-Bound Tables

    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.

    Data-bound tables in PrintDocument application.

    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
    //define render table
    RenderTable rt = new RenderTable();
    rt.Style.GridLines.All = LineDef.Default;
    // define data schema
    DataSource ds = CreateDemoDataSource();
    DataSet dsCities = new DataSet(ds, "SELECT Customer_demo.Company, [Order].* FROM (Customer_demo INNER JOIN[Order] ON Customer_demo.ID = [Order].CustomerID) ORDER BY Customer_demo.Company, [Order].PaymentType");
    doc.DataSchema.DataSources.Add(ds);
    doc.DataSchema.DataSets.Add(dsCities);
    // define data-binding within render table
    TableVectorGroup g = rt.RowGroups[0, 6];
    g.DataBinding.DataSource = dsCities;
    g.DataBinding.Grouping.Expressions.Add("Fields!Company.Value");
    // add aggregates
    doc.DataSchema.Aggregates.Add(new Aggregate("CompanySum", "Fields!PaymentAmount.Value", g.DataBinding, RunningEnum.Group, AggregateFuncEnum.Sum));
    doc.DataSchema.Aggregates.Add(new Aggregate("Sum", "Fields!PaymentAmount.Value", g.DataBinding, RunningEnum.Document, AggregateFuncEnum.Sum));
    g = rt.RowGroups[1, 4];
    g.DataBinding.DataSource = dsCities;
    g.DataBinding.Grouping.Expressions.Add("Fields!PaymentType.Value");
    doc.DataSchema.Aggregates.Add(new Aggregate("PaymentTypeCount", "Fields!PaymentAmount.Value", g.DataBinding, RunningEnum.Group, AggregateFuncEnum.Count));
    doc.DataSchema.Aggregates.Add(new Aggregate("PaymentTypeSum", "Fields!PaymentAmount.Value", g.DataBinding, RunningEnum.Group, AggregateFuncEnum.Sum));
    doc.DataSchema.Aggregates.Add(new Aggregate("PaymentTypeQuantity", "Fields!Quantity.Value", g.DataBinding, RunningEnum.Group, AggregateFuncEnum.Sum));
    g = rt.RowGroups[3, 1];
    g.DataBinding.DataSource = dsCities;
    // create aggregates
    doc.Body.Children.Add(rt);
    doc.Generate();
    

    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: