Stimulsoft – Non-Modal Designer in WPF App

Stimulsoft Reports is one among the most powerful and easy to use Reporting Tools available. While this post is not focused on feature of Stimulsoft Reports, it is worth checking out the features in Stimulsoft Website.

 

Embedded Stimulsoft Designer Control and MVVM

The post would rather focus on displaying the powerful Stimulsoft Designer in a WPF application with Data Source being .Net Objects created at runtime. While this is pretty straightforward to do when you want to invoke the designer as a Modal Dialog, it becomes a little messier when you want the designer to be an embedded control, particularly when you want to stick to the MVVM Pattern.
Let’s first go ahead and place our designer control in the View first.
<wpfdesign:StiWpfDesignerControl></wpfdesign:StiWpfDesignerControl>

Don’t miss out adding the namespace

xmlns:wpfdesign="clr-namespace:Stimulsoft.Report.WpfDesign;assembly=Stimulsoft.Report.WpfDesign"

For sake of example, we would mock our business object rather than taking it out of Database

   public class Products
   {
       public string Name { get; set; }
       public decimal Price { get; set; }
   }

var   _ProductCollection = new List()
  {
  new ProductModel() { Name = "Product 1", Price = 100 },
  new ProductModel() { Name = "Product 2", Price = 200 }
  };

We do have a property ‘ActiveReport’ , which holds the report details and is responsible for synchronizing the dictionary. Let’s define the Property and synchronize our collection.


  private Stimulsoft.Report.StiReport _ActiveReport;

  public Stimulsoft.Report.StiReport ActiveReport
  {
  get { return _ActiveReport; }
  set
  {
  _ActiveReport = value;
  this.NotifyOfPropertyChange(nameof(ActiveReport));
  }
  }

And the code to register the collection with StiReport.

  ActiveReport = new Stimulsoft.Report.StiReport();
  ActiveReport.RegBusinessObject("Products", _ProductCollection);
  ActiveReport.Dictionary.Synchronize();

This is where our problems begin. We do not have a property (the Report Property doesn’t allow Binding) exposed by Stimulsoft Designer to which could bind the StiReport Instance. We can do it pragmatically by assigning the Report Property, but that would involve breaking the MVVM Structure. We would prefer not to do that, atleast not directly. So what would be our workaround ?

Supervising Controller Pattern

The workaround lies with having a Supervising Controlling Pattern. The Supervising Controller allows the ViewModel to be aware of the View, but not depended on it. Now this can be a tricky situation if someone questions whether this would be breaking the MVVM, considering as per MVVM, the ViewModel should be completely independent of View. Pretty much true, but when all doors are closed, there is nothing wrong in making the ViewModel ‘aware‘ of View, as long as it is not dependent on View and we do minimalist code in View. Remember, there is a significant difference in being aware and being dependent.

So how do we implement the Supervising Controlling Pattern and make the ViewModel aware of the View. We first being by creating the Contract interface through which the ViewModel would be interacting with View. Let’s call it ISupervisorController

  public interface ISupervisingController
  {
  void UpdateReportControl(Stimulsoft.Report.StiReport Report);
  }

As you can see, it has a single method called UpdateReportControl, accepting the StiReport instance. Let’s go ahead and implement it in the View. We will make that only minimalist work is done in the code behind class.

  public void UpdateReportControl(StiReport Report)
  {
  ReportDesigner.Report = Report;
  }

So with that done, we come to the most important part – how do we get an instance of View in the ViewModel ? Thanks to Caliburn.Micro, we do have a solution for that as well.

Screen and IViewAware

The Screen class in Caliburn.Micro utilizes an interface ‘IViewAware, which exposes a method called OnViewAttached which gives us reference to the attached View. All that left to do is override the method and use our Supervising Controller interface to call the method from View, which sets the Report property of Designer Control

  protected override void OnViewAttached(object view, object context)
  {
  base.OnViewAttached(view, context);
  (view as ISupervisingController).UpdateReportControl(ActiveReport);
  }

That’s it, you have your .Net Object Collection synchronized with the Designer. The entire source code described in this post can be found here

Advertisement

One thought on “Stimulsoft – Non-Modal Designer in WPF App

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s