Working with Adapters for Report Elements

What is the Adapter?

In SharpShooter Rerpots (v6.2 and later) it is possible to change adapters which generate output elements in XAML export filters. Developers are able to override standard view and rendering algorithm of existing elements or create new custom element.

Actually XAML document which used in SharpShooter Reports.Silverlight is a result of work of XamlExportFilter export filter. It means that you can change the rendering methods for each report element by implementing custom adapters. I.e. you can set how the controls will be shown in Silverlight Viewer.

For example you can render a TextBox as a combination of TextBlocks (one for each line) or a single TextBlock for all lines. You can implement even more complicated construction (we basically use a combination of a Panel to layout the text and a TextBlock to output it).

How can I create my Adapter?
XAML export adapters extends XAMLAdapter class. To create your own adapter you need  to implement following method:

public abstract XmlElement ExportControl(XmlElement pageTag,
ReportControl reportControl,
IXamlContext context );
  • pageTag is a "parent" tag where the control is added
  • reportControl is a control being exported
  • context is used to get objects (pages, fonts) from server
This method creates XAML element based on reportControl and adds it to the XAML defined by pageTag parameter.

For example we have the following code of BoxXamlAdapter:

public class BoxXamlAdapter : XamlAdapter
{
    public override XmlElement ExportControl(
      XmlElement pageTag,
      ReportControl reportControl,
      IXamlContext context)
    {
        Box box = reportControl as Box;
     
        XmlElement rectTag = XamlBuilder.CreateChildElement( pageTag,
                                    ElementName.Rectangle);
  
         double width = Unit.Convert(box.Size.Width,
                    Unit.InternalUnit,
                    Unit.Pixel);
    
        double height = Unit.Convert(box.Size.Height,
                    Unit.InternalUnit,
                    Unit.Pixel);
     
        ...
        if (box is Picture || box is Widget ... )
        {
            ...
            XmlElement imageBrush = XamlBuilder.CreateChildElement(
                        fillContainer,
                        ElementName.ImageBrush);
    
            imageBrush.SetAttribute(AttributeName.ImageSource,
                    context.GetUrl(box));
            ...
            if (box is Picture)
            {
            ...
            }
        }
        else if (box.Fill != null && !(box.Fill is EmptyFill))
        {
            ...
        }
        if (box.Border != null && !box.Border.IsEmpty)
        {
            ...
        }
     
        return rectTag;
    }
...
}

How can I register my Adapter?

To register the adapter for the report element you needed to call the following method: 

XamlExportFilter.RegisterAdapter(Type controlType, Type adapterType);
  • controlType is a type of exported report element.
  • adapterType is a type for adapter for this control. 

Note: previously registered adapter for the specified controlType will be replaced by calling this method.

The example below demonstrates how you can replace the adapter for the TextBox elements (actually it shows how to use "old" adapter from v6.1 instead of "new" adapter introduced in v6.2).

public class ReportService : ReportServiceBase
{
 ReportService()
 {
    InitializeComponent();
    XamlExportFilter.RegisterAdapter(
        typeof(PerpetuumSoft.Reporting.DOM.TextBox),
        typeof(TextBoxXamlAdapter));
 }
 
}

Add Feedback