MVVM Command Binding in Windows Phone using Custom Delegates

Introduction:
Binding commands in MVVM is a bit tricky, but if understood correctly then of a great use.
A simple command can be bound using a Delegate and the Icommand Interface to handle the function that is to be executed.

Description:
First of all we need to know what a Delegate is?
A Delegate is a reference to a function. A Delegate is much useful in an event execution. Although this example deals with a custom Delegate we can use a predefined delegates present in the System Namespace.

Secondly and most importantly, ICommand interface and its implementation. ICommand can be found in System.Windows.Input namespace. ICommand interface provides all the method signatures that are used to execute a command in MVVM.

Here’s the code sample for commands in MVVM

MainPage.xaml

<phone:PhoneApplicationPage x:Class="CommandBindingMVVMDemo.MainPage"
                            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                            xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
                            xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
                            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                            xmlns:datacontext="clr-namespace:CommandBindingMVVMDemo"
                            mc:Ignorable="d"
                            FontFamily="{StaticResource PhoneFontFamilyNormal}"
                            FontSize="{StaticResource PhoneFontSizeNormal}"
                            Foreground="{StaticResource PhoneForegroundBrush}"
                            SupportedOrientations="Portrait"
                            Orientation="Portrait"
                            shell:SystemTray.IsVisible="True">

    <Grid>
        <Grid.DataContext>
            <datacontext:CommandBindingViewModel />
        </Grid.DataContext>

        <StackPanel>
            <Button Content="Click"
                    Height="100"
                    Name="btnClick"
                    Background="GreenYellow"
                    VerticalAlignment="Top"
                    Width="203"
                    Foreground="Black"
                    Command="{Binding ButtonCommand}" />
            <TextBox x:Name="tbMessage"
                     Text="{Binding MessageText, Mode=TwoWay}"
                     Margin="0,300,0,0" />
        </StackPanel>
    </Grid>
</phone:PhoneApplicationPage>

As for now the Data Context of the Grid object has been defined in the XAML. So no code piece is required in MainPage.xaml.cs. The Data Context assignment to the Grid object is handled therefore by the XAML itself.

Also here we will be following two way Binding to reflect any message we type in the text box named tbMessage.

Now let’s create a view model named as CommandBindingViewModel for the XAML defined in the MainPage.XAML. Below is the code for the ViewModel to the parent Grid of the MainPage.XAML.

CommandBindingViewModel.cs

using System.ComponentModel;
using System.Windows;
using System.Windows.Input;
namespace CommandBindingMVVMDemo
{
    public class CommandBindingViewModel : INotifyPropertyChanged
    {
        public string MessageText { get; set; }
        private ICommand m_ButtonCommand;
        public ICommand ButtonCommand
        {
            get{ return m_ButtonCommand;}
            set{ m_ButtonCommand = value;}
        }
        public CommandBindingViewModel()
        {
	     //initially set the value
            MessageText = "Start Text";
            OnPropertyChanged("MessageText");
            ButtonCommand=new CommandBinder(new CustomAction(ShowMessage));
        }
        public void ShowMessage(object obj)
        {
            MessageBox.Show(MessageText);
        }
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Let’s add a class called ComandBinder, which implements the interface Icommand and registers the command with the help of a Delegate. Below is the code details.

CommandBinder.cs

using System;
using System.Windows.Input;
namespace CommandBindingMVVMDemo
{
    class CommandBinder: ICommand
    {
        private CustomAction _action;
        public CommandBinder(CustomAction action)
        {
            _action = action;
        }
        public bool CanExecute(object parameter)
        {
            return true;
        }
        public event EventHandler CanExecuteChanged;
        public void Execute(object parameter)
        {
            if (parameter != null)
                _action(parameter);
        }
    }
    public delegate void CustomAction(object obj);
}

The delegate defined above contains a reference to the method ShowMessage. In the above code we have included the delegate, but that’s not mandatory it can be included in any Namespace and that we need to include while working with the delegate.

Summary:
Now the click event of the button will point to the function ShowMessage and once executed, will call the function to show the respective Text from the text box as a Message.

Written By: Anobik Dey, Software Developer, Mindfire Solutions

Advertisements

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 )

Google+ photo

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

Connecting to %s