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