Monday, 20 May 2013

Basics of Caliburn Micro in WPF mvvm–Part II Binding

In the first part of the MVVM using caliburn micro with WPF we saw how to write the bootstrapper to setup 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 power of MVVM.
Before we start I would recommend you to go through the previous article showing how to do setup. Once you done with the setup you can design the MainWindowView.Xaml file.
Naming Conventions in Caliburn micro
The caliburn micro built so that it can predict the view and viewmodel mapping just by the names. So if you view should be named like MainWindowView and your view model should be named as MainWindowViewModel. This way caliburn will automatically search for the view when loading the view model in the memory.
clip_image001
Designing MainWindowView
You can have multiple controls defined in your sample page. Let’s take the below 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 the caliburn micro is doing to provide in a easy to write code way.

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. Other setup we have done in the constructor of the MainWindowViewModel class.
Now here’s the magic start. You don’t have to write anything else so just press F5 and run the application.
You can ask question how the control 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 happened behind the scene, 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 have the same name as the Method. This is how the caliburn detects and map the property and method to the controls with their kind.
We’ll look at more advance stuff in upcoming posts on caliburn micro. So tuned in and happy programming.