Basics of Caliburn Micro in WPF MVVM - Part II Binding

In the first article of MVVM using Caliburn Micro with WPF we saw how to write the bootstrapper to set up everything for the Caliburn Micro library. Now in this part we'll see how to start creating new pages in the application and how the binding and events are being defined using this small library project with the power of MVVM. 

Before we start I recommend that you go through the previous article showing how to do the setup. Once you have done the setup you can design the MainWindowView.Xaml file.

Naming Conventions in Caliburn Micro

Caliburn Micro is built so that it can predict the view and viewmodel mapping just by the names. So if the view happens to be named MainWindowView then your view model should be named MainWindowViewModel. This way Caliburn will automatically search for the view when loading the view model into memory.

Img1.jpg

 Designing MainWindowView

You can have multiple controls defined in your sample page. Let's use the following as the sample view model:

    <Window x:Class="MainWindowView"

       ="" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

       ="" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

       ="" Title="{Binding DisplayName}" Height="350" Width="525"

       ="" WindowStyle="None" WindowState="Maximized" WindowChrome.IsHitTestVisibleInChrome="True" WindowStartupLocation="CenterScreen">

      <Grid>

            <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Width="350" Height="50">

            <TextBox x:Name="SearchText" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="12" Height="24" Width="100" />

            <Button x:Name="Search"></Button>             

    </StackPanel>       

  </Grid>
 
Now here we have a button and TextBox. Let's see the code for the View model of this window and what Caliburn Micro is doing to make it easy to code.
 

using System;

using System.ComponentModel;

using System.Windows;

using Caliburn.Micro;

 

using ILog = log4net.ILog;

 

namespace SampleApplication

{

    /// <summary>

    /// The main window view model.

    /// </summary>

    internal class MainWindowViewModel : Conductor<IScreen>.Collection.OneActive

    {

        /// <summary>

        /// The container.

        /// </summary>

        private readonly SimpleInjector.Container container;

 

        /// <summary>

        /// holds teh event aggregator

        /// </summary>

        private readonly IEventAggregator eventAggregator;

 

        /// <summary>

        /// The logger.

        /// </summary>

        private ILog logger;

 

        /// <summary>

        /// The searchText property.

        /// </summary>

        private string searchText;

 

        /// <summary>

        /// Initializes a new instance of the <see cref="MainWindowViewModel"/> class.

        /// </summary>

        /// <param name="container">

        /// The container.

        /// </param>

        /// <param name="eventAggregator">

        /// The event aggregator.

        /// </param>

        public MainWindowViewModel(SimpleInjector.Container container, IEventAggregator eventAggregator)

        {

            this.container = container;

 

            this.DisplayName = "Sample main window view model";

            this.eventAggregator = eventAggregator;

            this.eventAggregator.Subscribe(this);

            this.logger = this.container.GetInstance<ILog>();

            this.logger.Info("MainWindow view loaded");

        }

 

        /// <summary>

        /// Gets or sets the message.

        /// </summary>

        public string SearchText

        {

            get

            {

                return this.searchText;

            }

 

            set

            {

                this.searchText = value;

                this.NotifyOfPropertyChange(() => this.searchText);

            }

        }

        /// <summary>

        /// Search action

        /// </summary>

        public void Search()

        {

            MessageBox.Show(String.Format("Search is being performed for text {0}", this.SearchText));

        }

    }

}
 
So in the view model we have defined a property named SearchText and a void method named Search. We have done another setup in the constructor of the MainWindowViewModel class.

Now the magic begins. You don't have to write anything else so just press F5 and run the application.

You can ask how the controls on the view are bound to the property and the method is bound with the Click action of the button. Here's the magic that happens behind the scenes. We talked about the naming conventions. If you look at the View then we have the TextBox named same as the property defined in the Viewmodel, similarly the button has the same name as the Method. This is how Caliburn detects and maps the properties and methods to the controls with their kinds.

We'll look at more advanced stuff in future articles on Caliburn Micro. So stay tuned and happy programming.