Caliburn.Micro #005 : Bootstrapper with MEF

Previously, we learnt how to use SimpleContainer to set up our IoC Containers. We would be now looking into making the application more loosely coupled by leveraging the MEF. Just like with SimpleContainer, we would be focusing on the basic steps while configuring the IoC – Registering the IoC Container with Caliburn Micro and then registering the Service bindings. Let’s go ahead override the necessary methods

private CompositionContainer _Container;

protected override object GetInstance(Type service, string key)
{
  string contract = string.IsNullOrEmpty(key) ? AttributedModelServices.GetContractName(service) : key;
  var exports = _Container.GetExportedValues(contract);
  if (exports.Any())
      return exports.First();
  else
      throw new Exception("Could not find the key");
}

protected override void BuildUp(object instance)
{
  _Container.SatisfyImportsOnce(instance);
}

protected override IEnumerable GetAllInstances(Type service)
{
  return _Container.GetExportedValues(AttributedModelServices.GetContractName(service));
}

We will now go ahead and register our Service Bindings. This is where things get interesting.

protected override void Configure()
{
  _Container = new CompositionContainer(
                new AggregateCatalog(AssemblySource.Instance.Select(x=> new AssemblyCatalog(x)).OfType())
                );
  var batch = new CompositionBatch();
  batch.AddExportedValue(new WindowManager());
  batch.AddExportedValue(new EventAggregator());
  batch.AddExportedValue(_Container);

  _Container.Compose(batch);
}

As seen in the code above, we are using the AssemblySource to parse the ViewModels in the Assembly.

That’s it in Bootstrapper, but do not forget to decorate your View Model class with [Export()] Attribute and Constructor with [ImportingConstructor]. (For injecting dependency)

[Export(typeof(IReport))]
public class ReportViewModel :Screen, IReport
{
  [ImportingConstructor]
  publicReportViewModel(IEventAggregator EventAggregator)
  {
    // Do Constructor tasks
  }
}

We will delve into EventAggregators later, but for the moment, consider it an example of how to inject a dependency in the constructor when working with MEF.

Code sample for this post can be found here. The complete list of tutorials on Caliburn.Micro can be accessed here

 

Caliburn.Micro #004 : Bootstrapper with SimpleContainer

Let’s take a step back and look into our Bootstrapper in detail now. The first version of Bootstrapper we declared earlier is a rather simple one, without utilizing the some of the functionalities which takes Caliburn.Micro, or for that matter, any MVVM Framework ahead. The implementation of IoC Container.
We would be concentrating into two different IoC Containers – a Caliburn.Micro in-build container called SimpleContainer and the MEF (Microsoft Extensibility Framework) based Container. In this first part, we would be concentrating on the SimpleContainer. Let’s begin by declaring the interface contract for our Shell View Model.
  public interface IShell
  {

  }
I would leave the implementation of ShellViewModel and ShellView to the discretion of the reader, considering that is not what we are focusing on this particular session. We would instead focus on the Bootstrapper Class and how we would be triggering the ShellViewModel from it by utilizing the IoC container. We would however, write our OnStartup method, triggering the ShellViewModel through the IShell interface.
protected override void OnStartup(object sender, StartupEventArgs e)
{
  this.DisplayRootViewFor();
}
SimpleContainer
The first step is to configure the container with the Caliburn Micro Framework. We accomplish this by overriding 3 methods, the GetInstance, GetAllInstances and BuildUp.
private SimpleContainer _Container = new SimpleContainer();

protected override object GetInstance(Type service, string key)
{
  return _Container.GetInstance(service, key);
}

protected override IEnumerable GetAllInstances(Type service)
{
  return _Container.GetAllInstances(service);
}

protected override void BuildUp(object instance)
{
  _Container.BuildUp(instance);
}
Service Binding
Most of the code above are self explanatory. Having registered/configured your IoC Container with the framework, the next task is to register your contracts. We do this by overriding the Configure Method.
protected override void Configure()
{
  _Container.Instance(new WindowManager());
  _Container.Singleton();
  _Container.PerRequest();
}
Notice the three different methods we have used to register the service bindings. The Instance Method registers a pre-constructed instance with the type. This is similar to the Singleton method, however with a significant difference. The instance of Instance Method is pre-constructed while for the Singleton Method registration, the instance of Type is created only when first requested.
That’s it, the IoC container would now do the magic for us, by resolving the contracts when required.
There is another approach (method) to register the Service Binding, which focuses on auto-resolution of the Type by scanning the assembly for any implementation of the particular contract. For example, if we need to replace the service binding of IShell with assembly inspection, we would do the following.
 _Container.AllTypesOf(Assembly.GetExecutingAssembly());
In the next part of Caliburn.Micro Tutorial, we will look into implementing the IoC container with the more advanced, MEF based IoC Containers.
Sample code for this section can be found here. For complete list of tutorials on Caliburn.Micro, please follow this link

 

Stimulsoft – Non-Modal Designer in WPF App, Part 2

In the previous post, we explored Supervising Controller Pattern to provide a solution to the issue we faced when using Stimulsoft Designer  Controller as an embedded control in WPF application. Even while we used the Supervising Controller Pattern, we still fiddled with the MVVM pattern by making the ViewModel “aware” of the View, even though it wasn’t depended. In this section, we would be exploring another method, through which could eliminate the ‘awareness’ factor, allowing us to work along the MVVM pattern with all its purity.
As in previous section, we will begin by adding the designer control in our XAML.
<wpfdesign:StiWpfDesignerControl></wpfdesign:StiWpfDesignerControl>
So how do we do resolve the issue this time around, without breaking the MVVM pattern ? Instead of Supervising Controller Pattern, we would instead on something which is native to the WPF. The Behaviours and Attached Properties
Behavior and Attached Property
Behavior allows us to Attach a new property the StiWpfDesignerControl, which is bindable.
public class ReportBehavior : Behavior
    {
        public static readonly DependencyProperty ReportSourceProperty = DependencyProperty.RegisterAttached("ReportSource", typeof(object), typeof(ReportBehavior), new PropertyMetadata(ReportSourceChanged));

        private static void ReportSourceChanged(DependencyObject DependencyObject, DependencyPropertyChangedEventArgs PropertyChangedEvent)
        {
            var stidesigner = DependencyObject as StiWpfDesignerControl;

            if (stidesigner != null)
                stidesigner.Report = PropertyChangedEvent.NewValue as Stimulsoft.Report.StiReport;
        }

        public static void SetReportSource(DependencyObject target, object value)
        {
            target.SetValue(ReportSourceProperty, value);
        }

        public static object GetReportSource(DependencyObject target)
        {
            return target.GetValue(ReportSourceProperty);
        }
As can be seen in the code above, we have defined a property called “ReportSource” which allows us to the set the Report Property of the Designer Controller.  We can now bind our property in our XAML
Putting it all together
      <wpfdesign:StiWpfDesignerControl local1:ReportBehavior.ReportSource="{Binding Path=ActiveReport}" x:Name="DesignerControl"  ></wpfdesign:StiWpfDesignerControl>
Don’t forget the namespace
xmlns:local1="clr-namespace:CM005.Behaviour"

 

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

Caliburn Micro #003 : Events (Short Hand Syntax)

Previously, We looked at one approach of binding Events to Controls. However, the convention based approach is one of the least used approaches in Caliburn Micro. Think about it, if you need to bind more than one event to the control, say for example, the Click Event and MouseOver Event, this approach would fall short.
Thankfully, Caliburn Micro provides another approach, based on Event Triggers, which solves this problem. While there is a long annotation version of the approach, we would stick to the shorthand version, which is, designed to be more developer friendly.
 
Convention Based Approach
 
Let’s declare a button and assign a OnClick Event to the control using the convention based approach first.
 <Button  x:Name="ClearTextMethod">Clear</Button>

Now, Let’s change the signature to Event Trigger based approach. First, we need to add a namespace in our XAML Headers.

xmlns:cal="http://www.caliburnproject.org"

Event Trigger Based Approach
And now we will attach the event. Notice the change in Syntax.

<Button Content="Clear" cal:Message.Attach="[Event Click] = [Action ClearTextMethod]" />

As mentioned earlier, this approach allows us to attach more events to the Control. If we need to attach a MouseOver Event to the above button, all we need to do is add another pair of [Event][Action] separated by a semi-colon

<Button Content="Clear" cal:Message.Attach="[Event Click] = [Action ClearTextMethod];[Event MouseLeave]=[Action AnotherMethod]" />

Passing Parameter

We could also pass parameters to the method, with the same syntax.

A word of caution though when you pass a boolean parameter to the method. For example, invoking the method with following syntax doesn’t quite work.

<Button Content="Clear" cal:Message.Attach="[Event Click] = [Action ClearTextMethod(true)]" />

The workaround is fairly simple thought, just include a single quote around the string representing True/False. We can modify the syntax as following.

<Button Content="Clear" cal:Message.Attach="[Event Click] = [Action ClearTextMethod('true')]" />

Complete list of tutorials on Caliburn.Micro can be found here

Caliburn Micro #02 : BindableCollection & Events

In the previous part of this series, we looked into some of the basics of using Caliburn Micro. In this part, we will continue with few more examples, how to invoke a method on an event.

But before we do that, let’s expand our application a bit. Currently the application has two Text controls , wired up to a property (FirstName) in the View Model. Let’s expand it further and have 2 more properties, LastName and FullName.

Our expanded ViewModel Looks like following now.


private string _FirstName = "Jia Anu";

public string FirstName
 {
 get { return _FirstName; }
 set
 {
 _FirstName = value;
 NotifyOfPropertyChange(nameof(FirstName));
 NotifyOfPropertyChange(nameof(FullName));
 }
 }

private string _LastName;

public string LastName
 {
 get { return _LastName; }
 set {
 _LastName = value;
 NotifyOfPropertyChange(nameof(LastName));
 NotifyOfPropertyChange(nameof(FullName));
 }
 }

We will add additional controls to our View, and add the necessary binding.

        <!--Row 1 Starts here -->
        <Label Grid.Column="0" Grid.Row="0">Full Name</Label>
        <TextBlock Text="{Binding Path=FullName, Mode=OneWay}" Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2"></TextBlock>
        <!--Row 1 Ends here -->

        <!--Row 2 Starts here -->
        <Label Grid.Column="0" Grid.Row="1">First Name</Label>
        <TextBox x:Name="FirstName" Grid.Row="1" Grid.Column="1"></TextBox>
        <!--Row 2 Ends here -->

        <!--Row 3 Starts here -->
        <Label Grid.Column="0" Grid.Row="2">Last Name</Label>
        <TextBox x:Name="LastName" Grid.Row="2" Grid.Column="1"></TextBox>
        <!--Row 3 Ends here -->

Bindable Collections

Let’s expand it futher, let’s introduce a model now. We will add a model in our Model Folder.

public class DeparmentModel
{
public string DepartmentName { get; set; }
public string Supervisor { get; set; }

}

And introduce two new properties for our View Model.

private BindableCollection _DepartmentCollection = new BindableCollection();

public BindableCollection DepartmentCollection
{
get { return _DepartmentCollection; }
set
{
_DepartmentCollection = value;

}
}

private DeparmentModel _SelectedDepartment;

public DeparmentModel SelectedDepartment
{
get { return _SelectedDepartment; }
set
{
_SelectedDepartment = value;
NotifyOfPropertyChange(nameof(SelectedDepartment));
}
}

We will delve more into BindableCollection later, but for now, let’s think of it as a means for binding to a combo box. Since we are not using any Db for this example, lets hard code some values in the constructor.

public ShellViewModel()
{
DepartmentCollection.Add(new DeparmentModel() { DepartmentName = "Finance", Supervisor = "John Tommothy" });
DepartmentCollection.Add(new DeparmentModel() { DepartmentName = "Development", Supervisor = "Alex Brown" });
DepartmentCollection.Add(new DeparmentModel() { DepartmentName = "Human Resource", Supervisor = "Dennis Burton" });
}

We will add a Combo box and another Text Area in our XAML to accodomate the changes. The XAML looks like following now.

        <!--Row 4 Starts here -->
        <Label Grid.Column="0" Grid.Row="3">Department</Label>
        <ComboBox Grid.Column="1" Grid.Row="3" ItemsSource="{Binding DepartmentCollection}" DisplayMemberPath="DepartmentName"
                 SelectedItem="{Binding SelectedDepartment,Mode=OneWayToSource}" ></ComboBox>
                <!--Row 4 Ends here -->

        <!--Row 5 Starts here -->
        <Label Grid.Column="0" Grid.Row="4">Supervisor</Label>
        <TextBlock Grid.Column="1" Grid.Row="4" x:Name="SelectedDepartment_Supervisor"></TextBlock>
        <!--Row 5 Ends here -->

Run our application and you can now see the combo box in action. Everytime you change the Department, the corresponding Supervisor is displayed the TextArea.

Events and EventGuards

Now then, lets head to adding a button to clear the selected values. We will first introduce a method.

public void ClearTextMethod(string firstName,string lastName)
{
FirstName = string.Empty;
LastName = string.Empty;
}

We are passing two parameters, however we are not quite using it. However, the sigificance of the parameters come into light when we add our second method, CanClearTextMethod

public bool CanClearTextMethod(string firstName, string lastName)
{
return !string.IsNullOrEmpty(firstName);
}

Notice the naming patterns used for the methods and parameters. The ‘Can’ Method is named in such a way that it prepends ‘Can’ to the ClearTextMethod. This aids Caliburn Micro to recognize this method needs to be evaluated to enable CanClearTextMethod.

Also the parameters. They are named as similiar as the FirstName and LastName Properties. These are the properties which dictate whether to enable the method or not, which is being passed as paramers. Ensure the naming is correct and Caliburn Micro does the magic for you.

Lets add the necessary XAML for adding a button and wiring it up with the method.

        <Button Grid.Column="0" Grid.Row="5" x:Name="ClearTextMethod">Clear</Button>

The entire code sample for this examples can be found here. 

Complete List of Tutorials on Caliburn.Micro can be found here

Caliburn Micro #01 : Introduction

It has been long since i blogged, having caught up with the Product Release and Year End Vaccations. As the calender turns, it would be a good time to learn something new.

If you are building an WPF application and is looking out for MVVM Frameworks, you would be surprised with the amount of choices you are bestowed with. Despite Prism standing out as aruguably the most complete package available, there are times when you would like to try out a different framework. That brings us to Caliburn Micro, a light weight MVVM Framework, which might not be as powerful as Prism, but still does its work in a simple and easy way.

Bonus :  Caliburn.Micro Starter Kit Extensions for WPF is now available at Visual Studio Marketplace

Okay, that’s for an Intro, lets get our hands dirty and create a customary ‘Hello World’ app using Caliburn Micro. Let’s kick start our Visual Studio , create a new WPF Application and do the obvious step, add ‘Caliburn Micro’ Nuget package.

CM Demo 01.JPG

Once you have the necessary dependencies in, we will start with creating our ‘Hello World’ application. Normal WPF application would have ideally looked for the “StartupUri” Tag under your app.xaml to kick start your first page. The Caliburn.Micro works differently. So lets first go ahead and remove the StartUri tag and replace it with bit of XAML to ensure it takes advantages of features of Caliburn.Micro.

Our App.Xaml would now look like following.

<Application x:Class="App001.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:App001"
             >
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary>
                    <local:Bootstrapper x:Key="Bootstrapper"></local:Bootstrapper>
                </ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

As you can see we have replaced the StartupUri and added a Resource Dictionary called Bootstrapper. At this point, Bootstrapper doesn’t exist, so we will go ahead and create it. Bootstrapper will act as the entry point for our WPF application and would point to the Screen that needs to be loaded first.


public class Bootstrapper : BootstrapperBase
 {
 #region Constructor
 public Bootstrapper()
 {
 Initialize();
 }
 #endregion

 protected override void OnStartup(object sender, StartupEventArgs e)
 {
 DisplayRootViewFor();
 }
}

As seen in the code above, the Bootstrapper class is derieved from BootstrapperBase class from the Caliburn.Micro library. We have done two things here.
a) Called the Initialize method in the default constructor.
b) Override ‘OnStartUp’ method and called a single method, DisplayRootViewFor, pointing to the Base View Model which we want to load first. In this particular example, we have called it ShellViewModel.

As in the earlier case, we do not have the ShellViewModel class defined at the moment, which obviously becomes our next step. Prior to which, we will create 3 folders, each representing the three components of MVVM in the project – Models, Views, ViewModels. Remember naming the folders exactly the same, with names denoting plurals, so that we can take advantage of the Caliburn Magic.

We will now create the ShellViewModel Class under the ViewModels Folder.


public class ShellViewModel:Screen
{
}

Let’s keep it simple for the moment, san any properties and derieve it from Screen Class ( we will delve into other derivative options later). We will add the View for the ViewModel, again keeping it devoid of complicated controls for the sake of example.

        <TextBlock Text="Jia"></TextBlock>
        <TextBox>Jia</TextBox>

As seen the in code above, we have called it ShellView and have placed it under the Views Folder. The naming is of foremost importance here as the Caliburn Framework relies heavily on the naming conventions to wireup the View and View Model. Unlike, Prism you don’t need to set the ‘Autowireviewmodel’ property, this is being automatically done by the Caliburn framework as long as you follow the naming convensions.

For sake of simplicity being the first example, we have hard coded the values for TextBlock and TextBox, we will replace it with binding as we move on with the example.

That’s it, you are all set to run the basic ‘Hello World’.

Okay, let’s now add couple of Properties and bind them to our controls. Let’s go ahead and create the properties in ViewModel.


private string _FirstName = "Jia Anu";

public string FirstName
{
get { return _FirstName; }
set
{
_FirstName = value;
NotifyOfPropertyChange(nameof(FirstName));
}
}

Now let’s head towards the View and wireup the FirstName property. Modified XAML looks as below.

           <TextBlock Text="{Binding Path=FirstName, Mode=OneWay}" ></TextBlock>
        <TextBox x:Name="FirstName" ></TextBox>

Now you can run the application and see the magic of MVVM model in action via Caliburn Micro. In the next post, we will delve more into the CM features. The code for this project can be found here