MindFusion.Reporting for Silverlight Programmer's Guide
Supplying Data for the Report

The data for a report is supplied through its DataContext property. This could be either a DataSet, a collection or any other arbitrary object. Items within the report can bind to various properties of the supplied data object using common Silverlight bindings. The following example illustrates a report containing a label. The label in the report has its Text property bound to the StringValue property of the report's DataContext object.

XAML  Copy Code

<r:Report x:Name="report">
  <r:Report.DataContext>
    <l:SomeObject StringValue="someValue" />
  </r:Report.DataContext>
  <r:Page>
    <r:Label Text="{Binding StringValue}" />
  </r:Page>
</r:Report>

The DataContext property of the report is inherited by its children, which means that if an item in the report does not have an explicitly set DataContext, it will inherit the DataContext of its parent item. In the sample above the Page inherits the DataContext from the report and the Label in turn inherits it from the page. There are exceptions to this rule as outlined in the section below.

Using DataRange objects

The DataRange items are used to display lists of elements - for example arrays or data tables. Therefore, it is required that the data object supplied to the DataRange implements the IEnumerable interface. The DataRange object provides an ItemTemplate property, which defines the template of the individual objects in the supplied data.

The data for the DataRange is supplied through its DataSource property. If the value of this property is null (Nothing in Visual Basic) the DataRange raises the QueryDetails event on its containing report passing its current DataContext object as a master row. If the event does not yield a result, the DataRange uses its current DataContext as a data source.

When the DataRange processes its data source, it creates an instance of the template specified by the ItemTemplate property for each object in the data source. The DataContext of these new instances is set to the corresponding object in the data source. For example, if the DataRange displays a table with ten records, ten new instances of the ItemTemplate are created and the DataContext of each new instance is set to the corresponding record in the database table.

In the following example a DataRange is bound to the Employee table in an existing data set. The data set is expected to be set as a DataContext of the report, containing the DataRange.

XAML  Copy Code

...
<r:DataRange DataSource="{Binding Employees}" />
...

The DataRange in the above example can provide an ItemTemplate for the objects in its data source. Assuming that the Employee table has a column, named FirstName, the following example demonstrates a label which binds its Text to this column:

XAML  Copy Code

...
<r:DataRange DataSource="{Binding Employees}">
  <r:DataRange.ItemTemplate>
    <DataTemplate>
      <r:ItemContainer>
        <r:Label Text="[FirstName]" />
      </r:ItemContainer>
    </DataTemplate>
  </r:DataRange.ItemTemplate>
</r:DataRange>
...

Note that the root element of the DataTemplate object provided by the ItemTemplate should always be an ItemContainer object.

Master detail relations

MindFusion.Reporting for Silverlight supports master detail relation through data range composition. You need to create a data range, bound to the master data. Then you need to create another data range as a child of the first one. The details data for the embedded data range is then supplied through the QueryDetails event of the report. The inner data range usually provides a name so that it can be identified in the QueryDetails event handler. Here is a XAML code defining two embedded data ranges:

XAML  Copy Code

...
<r:DataRange DataSource="{Binding Employees}">
  <r:DataRange.ItemTemplate>
    <DataTemplate>
      <r:ItemContainer>
        <r:DataRange Name="OrdersRange" />
      </r:ItemContainer>
    </DataTemplate>
  </r:DataRange.ItemTemplate>
</r:DataRange>
...

The following code illustrates a sample QueryDetails event handler, which supplies the details data for the inner data range. The example relies on a GetEmployeeOrders method, which takes care of the actual retrieval of the orders for a specific employee.

C#  Copy Code

void report_QueryDetails(object sender, QueryDetailsEventArgs e)
{
    DataRange dataRange = sender as DataRange;
    if (dataRange != null)
    {
        if (dataRange.Name == "OrdersRange")
        {
            // Obtains the orders related to the corresponding employee
            e.Details = GetEmpoyeeOrders(e.MasterRow);
        }
    }
}

Visual Basic  Copy Code

Sub myReport_QueryDetails(ByVal sender As Object, ByVal e As QueryDetailsEventArgs)

    Dim dataRange As DataRange = sender
    If (Not dataRange Is Nothing) Then

        If (dataRange.Name = "ProductsRange") Then

            e.Details = GetEmployeeOrders(e.MasterRow)

        End If

    End If

End Sub