Category Archives: .NET

Basics of Command Binding Using ICommand

ICommand is used to define a command. The interface contains the following information.

public interface ICommand
{
    //has 2 methods
    void Execute(object parameter);
    bool CanExecute(object parameter);

    //1 event
    event EventHandler CanExecuteChanged;
}

ICommand interface consists of the following:

Two methods:
CanExecute : Defines the method that determines whether the command can execute in its current state.
Execute : Defines the method to be called when the command is invoked.

One Event:
CanExecuteChanged: Occurs when changes occur that affect whether or not the command should execute.

You implement the ICommand interface on a class, provide a way for command handlers to hook up, and then do the routing when the command is invoked. You also must decide what criteria you will use for determining when to raise the CanExecuteChanged event. Using custom ICommand implementations allows us to provide our own routing mechanisms, particularly ones that are not tied to the visual tree and that can support multiple command handlers. Given an instance of an ICommand, you just call Execute, and it does whatever it’s supposed to do. Except you shouldn’t call it if it’s CanExecute is false. If you want to know when CanExecute might be willing to give you a different answer, listen to the CanExecuteChanged event.

Lets try a simple hello world application using the IComand. First, declare a class derived from ICommand and name it as MyFirstCommand. Since the class MyFirstCommand is derived from ICommand, we need to implement the interface as shown below. Whenever the command is executed, it calls the Execute() method to show a Hello World message box.

public class MyFirstCommand : ICommand
{
    public void Execute(object parameter)
    {
        MessageBox.Show("Hello world");
    }

    public bool CanExecute(object parameter)
    {
        return true;
    }
    public event EventHandler CanExecuteChanged;
}

 

Once you have an ICommand instance handy, you can give it to a Button (on the Button.Command property), and Button knows what to do with it. As the simplest example, you can do this with the previous command:

First, we need to create get the class namespace into XAML using the following code. To know more about Instantiating an Object as a resource in XAML see the link https://kishore1021.wordpress.com/2010/02/06/instantiating-an-object-as-a-resource-in-xaml/

xmlns:local="clr-namespace:CommandBinding2"

 

Create a resource in the Grid class as shown below.

<Grid.Resources>
            <local:MyFirstCommand x:Key="hwc"/>
        </Grid.Resources>

Create a button inside the grid and assign the resource we created in the above code to the button command property.

Button Content="Hello World" Height="36" HorizontalAlignment="Left" Margin="12,115,0,0" Name="button1" VerticalAlignment="Top" Width="116"
                Command="{StaticResource hwc}"/>
   

 

If you do that, you’ll notice that the Button is enabled. In the CanExecute() method, if we have not returned true, then the button would have appeared as disabled. That’s because Button knows to call CanExecute, but we haven’t specified a parameter, and recall from above that if you pass null as an argument to CanExecute it returns false. So Button has a CommandParameter property that lets you specify what will be passed to CanExecute and Execute:

Now the button is enabled, and if you click on it, you’ll see “Hello, world” in the debug output window.

This actually isn’t just a Button feature, it’s actually in the base class ButtonBase. And MenuItem is a ButtonBase. So MenuItem can use the ICommand too. If MenuItem’s Command property is set to the Static resource hwc, it will also behave the same.

Passing parameter to the Command

Lets go through the hello world code discussed above and change it a bit to use the command parameters. In the Button class, set the CommandParameter property to some text like “Hello, World” as shown in the following code.

<Button Content="Hello World" Height="36" HorizontalAlignment="Left" Margin="12,115,0,0" Name="button1" VerticalAlignment="Top" Width="116"
                CommandParameter="Hello, World"
                Command="{StaticResource hwc}"/>
    

 

In the code file, change the Execute() method to show the parameter passed to the command. Modify the CanExecute() method to return true if the command parameter contains a value otherwise return false as shown in the following code.

public class MyFirstCommand : ICommand
{
    public void Execute(object parameter)
    {
        MessageBox.Show(parameter.ToString());
    }

    public bool CanExecute(object parameter)
    {
        if (parameter != null)
            return true;
        else
            return false;
    }
    public event EventHandler CanExecuteChanged;
}

 

Run the project and see the magic yourself.

Going further with ICommand:

 

image

Figure 1: Class diagram of the participating classes

A good starting point for creating a custom command is to use delegates. A delegate already supports invocation of a target method, and it also supports multiple subscribers. In the above diagram, have a student class and a UISaveCommand class that the MainWindow uses. The idea is that when I click on Save Button as shown in Fig 2, it should call the Save() method. But the Button Command doesn’t know where the Save() method is present. So the UISaveCommand class uses the Func<>.

image

Figure 2: Output window

Step 1:

Let us create a UISaveCommand class derived from ICommand interface and implement the interface in that class as shown below. In the CanExecute() method we are checking to see if the function pointer (funcpointer) is pointing to a valid or not. If it points to a valid function, we return true otherwise return false. The Execute() method just calls the method pointed to by the function pointer (delegate).

public class UISaveCommand : ICommand
{
    public Func<int> funcpointer
    {
        get;
        set;
    }

    public bool CanExecute(object parameter)
    {
        if (funcpointer != null)
        {
            return true;
        }
        else
            return false;

        throw new NotImplementedException();
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public void Execute(object parameter)
    {
        if (funcpointer != null)
        {
            funcpointer();
        }

    }
}

Func<> is declared as public delegate TResult Func<out TResult>(); It encapsulates a method that has no parameters and returns a value of the type specified by the TResult parameter. In the MainWindow class, create an object of UISaveCommand class and assign the funcpointer to Save() method as shown below. So we are binding the method present in one class from other place using Command.

public partial class MainWindow : Window
{
    Student stobj = new Student();

   public MainWindow()
    {
        InitializeComponent();
        
        UISaveCommand savecommand = new UISaveCommand();
        savecommand.funcpointer = Save;
        stobj.StudentClassCommand = savecommand;
        this.DataContext = stobj;
    }

   public int Save()
   {
       MessageBox.Show(stobj.FirstName + stobj.LastName);
       return 0;
   }
}

Then we assign the savecommand object to the Student class property of type ICommand. Following is the code of the Student class.

public class Student : INotifyPropertyChanged
    {
       public ICommand StudentClassCommand
       {
           get;
           set;
       }

        private string firstname;

        public string FirstName
        {
            get { return firstname; }
            set
            {
                firstname = value;
                OnPropertyChanged("FirstName");
            }
        }

        private string lastname;

        public string LastName
        {
            get { return lastname; }
            set
            {
                lastname = value;
                OnPropertyChanged("LastName");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        
    }

The complete code of .CS file is

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;

namespace CommandBinding2
{
    public class MyFirstCommand : ICommand
    {
        public void Execute(object parameter)
        {
            MessageBox.Show(parameter.ToString());
        }

        public bool CanExecute(object parameter)
        {
            if (parameter != null)
                return true;
            else
                return false;
        }
        public event EventHandler CanExecuteChanged;
    }

    public class UISaveCommand : ICommand
    {
        public Func<int> funcpointer
        {
            get;
            set;
        }

        public bool CanExecute(object parameter)
        {
            if (funcpointer != null)
            {
                return true;
            }
            else
                return false;

            throw new NotImplementedException();
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public void Execute(object parameter)
        {
            if (funcpointer != null)
            {
                funcpointer();
            }

        }
    }

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        Student stobj = new Student();

       public MainWindow()
        {
            InitializeComponent();
            
            UISaveCommand savecommand = new UISaveCommand();
            savecommand.funcpointer = Save;
            stobj.StudentClassCommand = savecommand;
            this.DataContext = stobj;
        }

       public UISaveCommand savecommand
       {
           get
           {
               throw new System.NotImplementedException();
           }
           set
           {
           }
       }

       public int Save()
       {
           MessageBox.Show(stobj.FirstName + stobj.LastName);
           return 0;
       }
    }

   public class Student : INotifyPropertyChanged
    {
       public ICommand StudentClassCommand
       {
           get;
           set;
       }

        private string firstname;

        public string FirstName
        {
            get { return firstname; }
            set
            {
                firstname = value;
                OnPropertyChanged("FirstName");
            }
        }

        private string lastname;

        public string LastName
        {
            get { return lastname; }
            set
            {
                lastname = value;
                OnPropertyChanged("LastName");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        
    }

    ////public class StringDelegateCommand : ICommand
    ////{
    ////    Action<string> m_ExecuteTargets = delegate { };
    ////    Func<bool> m_CanExecuteTargets = delegate { return false; };
    ////    bool m_Enabled = false;

    ////    public bool CanExecute(object parameter)
    ////    {
    ////        Delegate[] targets = m_CanExecuteTargets.GetInvocationList();
    ////        foreach (Func<bool> target in targets)
    ////        {
    ////            m_Enabled = false;
    ////            bool localenable = target.Invoke();
    ////            if (localenable)
    ////            {
    ////                m_Enabled = true;
    ////                break;
    ////            }
    ////        }
    ////        return m_Enabled;
    ////    }
        
    ////    public void Execute(object parameter)
    ////    {
    ////        if (m_Enabled)
    ////            m_ExecuteTargets(parameter != null ? parameter.ToString() : null);
    ////    }
        
    ////    public event EventHandler CanExecuteChanged = delegate { };

    ////    public event Action<string> ExecuteTargets
    ////    {
    ////        add { m_ExecuteTargets += value; }
    ////        remove { m_ExecuteTargets -= value; }
    ////    }

    ////    public event Func<bool> CanExecuteTargets
    ////    {
    ////        add { m_CanExecuteTargets += value; CanExecuteChanged(this, EventArgs.Empty); }
    ////        remove { m_CanExecuteTargets -= value; CanExecuteChanged(this, EventArgs.Empty); }
    ////    }
    ////}
}

 

The complete code of XAML file is

<Window x:Class="CommandBinding2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml&quot;
        xmlns:local="clr-namespace:CommandBinding2"
        Title="MainWindow" Height="282" Width="474">
    <Grid Height="295" Width="440">
        <Grid.Resources>
            <local:MyFirstCommand x:Key="hwc"/>
        </Grid.Resources>

        <TextBlock Text="Enter First Name" Margin="0,0,271,261"></TextBlock>
        <TextBox Margin="175,6,12,260" Name="txtFirstName" VerticalAlignment="Center" Text="{Binding Path=FirstName}" Height="26" />
        <TextBlock Margin="0,48,324,216" VerticalAlignment="Center" Text="Enter Last Name" Height="28" />
        <TextBox Margin="175,55,12,215" Name="txtLastName" VerticalAlignment="Center" Text="{Binding Path=LastName}"/>
        <Button Margin="187,102,0,144" Content="Save"
                Command="{Binding StudentClassCommand}" />
        <Button Content="Hello World" Height="36" HorizontalAlignment="Left" Margin="12,115,0,0" Name="button1" VerticalAlignment="Top" Width="116"
                CommandParameter="Hello, World"
                Command="{StaticResource hwc}"/>
    </Grid>
</Window>

 

Attitude determines altitude. – Anonymous

Introduction to Command Binding

We have seen the abc’s of Data Binding here. If you have worked in VC++, then you are aware of some of the semantics of WPF command binding. Basically, commands are nothing but actions performed on the applications using input mechanism. commands are abstract and loosely-coupled version of events. Whereas events are tied to details about specific user actions (such as a Button being clicked or a List Item being selected), commands represent actions independent from their user interface exposure. Canonical examples of commands are Cut, Copy, and Paste. In VC++ MFC, we declare commands and then define the functions that execute the command action. Similarly, in WPF, the semantics and the object that invokes a command is separated from the logic that executes the command. This allows for multiple and disparate sources like MenuItems in a Menu, MenuItems on a Context Menu(Right Click), Buttons on a ToolBar, keyboard shortcuts(CTRL+X for Cut), and so on, to invoke the same command logic, and it allows the command logic to be customized for different targets. We used to perform similar design in VC++ too.

In VC++ MFC application, for example, the editing operations Copy, Cut, and Paste, can be invoked by using different user actions if they are implemented by using commands. An MFC application might allow a user to cut selected text by either choosing an Cut item in edit menu, or Cut in right click menu, or using a key combination, such as CTRL+X. By using commands, you can bind each type of user action to the same logic. In VC++, we assign ID’s to each command like ID_EDIT_COPY, ID_EDIT_CUT and ID_EDIT_PASTE. WPF supports similar concepts but uses a different mechanism to achieve it. By using commands, you can bind each type of user action to the same logic. Another purpose of commands is to indicate whether an action is available. To continue the example of cutting an object or text, the action only makes sense when something is selected. If a user tries to cut an object or text without having anything selected, nothing would happen. To indicate this to the user, many applications disable buttons and menu items so that the user knows whether it is possible to perform an action.

A command is any object implementing the ICommand interface (from System.Windows.Input), which defines two methods and one event:

  • Execute—The method that executes the command-specific logic
  • CanExecute—A method returning true if the command is enabled or false if it is disabled
  • CanExecuteChanged—An event that is raised whenever the value of CanExecute changes

Steps to create a Command:

  1. Say you want to create a Cut Command. We need to implement a class that implements ICommand.
  2. Call Execute from relevant event handlers (when CanExecute returns true)
  3. Handle the CanExecuteChanged event to toggle the IsEnabled property on the relevant pieces of user interface.

Fortunately, controls such as Button, CheckBox, and MenuItem have logic to interact with any command on your behalf. They expose a simple Command property (of type ICommand). When set, these controls automatically call the command’s Execute method (when CanExecute returns true) whenever their Click event is raised. In addition, they automatically keep their value for IsEnabled synchronized with the value of CanExecute by leveraging the CanExecuteChanged event. By supporting all this via a simple property assignment, all of this logic is available from XAML. Some of WPF’s controls have built-in behavior tied to various commands. 

WPF’s built-in commands like Cut, Copy, Paste are exposed as static properties and they are all instances of RoutedUICommand, a class that not only implements ICommand, but supports bubbling just like a routed event. A command can indicate whether an action is possible by implementing the CanExecute method. A button can subscribe to the CanExecuteChanged event and be disabled if CanExecute returns false or be enabled if CanExecute returns true.

WPF defines a bunch of commands already, so you don’t have to implement ICommand objects for Cut, Copy, and Paste and worry about where to store them. WPF’s built-in commands are exposed as static properties of five different classes:

  • ApplicationCommands—Close, Copy, Cut, Delete, Find, Help, New, Open, Paste, Print, PrintPreview, Properties, Redo, Replace, Save, SaveAs, SelectAll, Stop, Undo, and more
  • ComponentCommands—MoveDown, MoveLeft, MoveRight, MoveUp, ScrollByLine, ScrollPageDown, ScrollPageLeft, ScrollPageRight, ScrollPageUp, SelectToEnd, SelectToHome, SelectToPageDown, SelectToPageUp, and more
  • MediaCommands—ChannelDown, ChannelUp, DecreaseVolume, FastForward, IncreaseVolume, MuteVolume, NextTrack, Pause, Play, PreviousTrack, Record, Rewind, Select, Stop, and more
  • NavigationCommands—BrowseBack, BrowseForward, BrowseHome, BrowseStop, Favorites, FirstPage, GoToPage, LastPage, NextPage, PreviousPage, Refresh, Search, Zoom, and more
  • EditingCommands—AlignCenter, AlignJustify, AlignLeft, AlignRight, CorrectSpellingError, DecreaseFontSize, DecreaseIndentation, EnterLineBreak, EnterParagraphBreak, IgnoreSpellingError, IncreaseFontSize, IncreaseIndentation, MoveDownByLine, MoveDownByPage, MoveDownByParagraph, MoveLeftByCharacter, MoveLeftByWord, MoveRightByCharacter, MoveRightByWord, and more

Each of these properties does not return a unique type implementing ICommand. Instead, they are all instances of RoutedUICommand, a class that not only implements ICommand, but supports bubbling just like a routed event.

image

Lets develop a dialog that has a “Help” button, when clicked will open the help webpage. Let’s demonstrate how these built-in commands work by attaching some logic with the Help command defined in ApplicationCommands. Assuming the Button is named helpButton, you can associate it with the Help command in C# as follows:

helpButton.Command = ApplicationCommands.Help;

All RoutedUICommand objects define a Text property containing a name for the command that’s appropriate to show in a user interface. (This property is the only difference between RoutedUICommand and its base RoutedCommand class.) For example, the Help command’s Text property is (unsurprisingly) set to the string Help. The hard-coded Content on this Button could therefore be replaced as follows:

helpButton.Content = ApplicationCommands.Help.Text;

If you were to run the dialog with this change, you would see that the Button is now permanently disabled. That’s because the built-in commands can’t possibly know when they should be enabled or disabled, or even what action to take when they are executed. They delegate this logic to consumers of the commands. To plug in custom logic, you need to add a CommandBinding to the element that will execute the command or any parent element (thanks to the bubbling behavior of routed commands). All classes deriving from UIElement (and ContentElement) contain a CommandBindings collection that can hold one or more CommandBinding objects. Therefore, you can add a CommandBinding for Help to the dialog’s root Window as follows in

<Window.CommandBindings>
        <CommandBinding Command="Help"
                        CanExecute="CommandBinding_CanExecute"
                        Executed="CommandBinding_Executed" />
    </Window.CommandBindings>

 

Or in its code-behind file:

this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Help,
        CommandBinding_Executed, CommandBinding_CanExecute));

The methods called CommandBinding_Executed and CommandBinding_CanExecute have to be defined in code behind file as follows. These methods will be called back at appropriate times in order to plug in an implementation for the Help command’s CanExecute and Execute methods.

private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    if (firstName.Text == "help")
        e.CanExecute = true;
    else
        e.CanExecute = false;

}

private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
    System.Diagnostics.Process.Start("https://kishore1021.wordpress.com/&quot;);

}

 

In the XAML file, assign the command to the help button as follows.

<Button Grid.Row="3" Grid.Column="1" Command="Help"
          Name="MyHelpButton" Margin="4,190,0,5">
            Help
        </Button>

 

Compile the project and run the application. Initially, the help button is disabled. Enter help in the first name textbox and you can see that the help button is enabled. Now to take advantage of command binding, say you want to bring up help when user presses keyboard shortcut F2 key. We can bind our own input gestures to a command by adding KeyBinding and/or MouseBinding objects to the relevant element’s InputBindings collection in code as follows

this.InputBindings.Add(
              new KeyBinding(ApplicationCommands.Help, new KeyGesture(Key.F2)));

The same binding can be performed in XAML as follows

<Window.InputBindings>
    <KeyBinding Command="Help" Key="F2"/>
    <KeyBinding Command="NotACommand" Key="F1"/>
</Window.InputBindings>

 

The complete XAML code is

<Window x:Class="CommandBinding101.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml&quot;
        Title="MainWindow" Height="350" Width="525">
    <Window.CommandBindings>
        <CommandBinding Command="Help"
                        CanExecute="CommandBinding_CanExecute"
                        Executed="CommandBinding_Executed" />
    </Window.CommandBindings>
    <Window.InputBindings>
        <KeyBinding Command="Help" Key="F2"/>
        <KeyBinding Command="NotACommand" Key="F1"/>
    </Window.InputBindings>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="30"/>
            <RowDefinition Height="30"/>
            <RowDefinition Height="30"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <Label>
            Enter your first name:
        </Label>
        <TextBox Grid.Row="0" Grid.Column="1"
           Name="firstName" Margin="0,5,10,5"/>

        <Label Grid.Row="1" >
            Enter your last name:
        </Label>
        <TextBox Grid.Row="1" Grid.Column="1"
           Name="lastName" Margin="0,5,10,5"/>

        <Button Grid.Row="2" Grid.Column="0"
          Name="Clear" Margin="2" Click="Clear_Click">
            Clear Name
        </Button>

        <Button Content="Enable Help" Margin="2" Name="button1" Grid.Column="1" Grid.Row="2" Click="button1_Click" />
        
        <Button Grid.Row="3" Grid.Column="1" Command="Help"
          Name="MyHelpButton" Margin="4,190,0,5">
            Help
        </Button>
        <Label Content="Type help in the first name edit box to enable the Help button" Margin="-1,13,12,164" Grid.Row="3" Grid.ColumnSpan="2" />
    </Grid>
    
</Window>

The complete code behind is

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace CommandBinding101
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            //MyHelpButton.Command = ApplicationCommands.Help;

           // this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Help,
           //  CommandBinding_Executed, CommandBinding_CanExecute));

            //this.InputBindings.Add(
            //  new KeyBinding(ApplicationCommands.Help, new KeyGesture(Key.F2)));

        }

        private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (firstName.Text == "help")
                e.CanExecute = true;
            else
                e.CanExecute = false;

        }

        private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            System.Diagnostics.Process.Start("https://kishore1021.wordpress.com/&quot;);

        }

        private void Clear_Click(object sender, RoutedEventArgs e)
        {
            firstName.Clear();
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            firstName.Text = "help";
        }
    }
}

If you use one of the preexisting RoutedUICommand objects for a WPF command, e.g. ApplicationCommands.Open, you’ll notice that the RoutedUICommand instance has a Text property.  This property in the command is used to set the label appearing on any MenuItem instances that have attached to the command by setting their Command property.  You don’t need to set the menu item’s Header property explicitly.

Download the source code here

If you really want the key to success, start by doing the opposite of what everyone else is doing.

Delegates & Events

DELEGATES:

A delegate is a reference type that can be used to encapsulate a named or an anonymous method. Delegates are similar to function pointers in C++; however, delegates are type-safe and secure. Delegate types are implicitly sealed. Delegates are the basis for Events. Delegates are object-oriented. A delegate can be passed like any other variable. This allows the method to be called anonymously, without calling the method directly

A delegate will allow us to specify what the function we’ll be calling looks like without having to specify which function to call. The declaration for a delegate looks just like the declaration for a function, except that in this case, we’re declaring the signature of functions that this delegate can reference.

There are three steps in defining and using delegates:

1. Declaring a delegate : The declaration of a delegate type is similar to a method signature. It has a return value and any number of parameters of any type:

// Declare delegate — defines required signature:
delegate double MathAction(double num);

This declaration defines a delegate named MathAction, which will encapsulate any method that takes one double as parameter and returns a double.

2. Instantiating/creating a delegate : Once a delegate type has been declared, a delegate object must be created and associated with a particular method. Like all other objects, a new delegate object is created with a new expression. When creating a delegate, however, the argument passed to the new expression is special — it is written like a method call, but without the arguments to the method.

// Instantiate delegate with named method:
MathAction madelegate = Double;

3. Calling a delegate : Once a delegate object is created, the delegate object is typically passed to other code that will call the delegate. A delegate object is called by using the name of the delegate object, followed by the parenthesized arguments to be passed to the delegate.

// Invoke delegate madelegate:
double multByTwo = madelegate(4.5);

A delegate declaration defines a type that encapsulates a method with a particular set of arguments and return type. For static methods, a delegate object encapsulates the method to be called. For instance methods, a delegate object encapsulates both an instance and a method on the instance. If you have a delegate object and an appropriate set of arguments, you can invoke the delegate with the arguments.

A delegate can be instantiated by associating it either with a named or anonymous method or lambda expression that has a compatible return type and input parameters.

The following sample demonstrates the concepts explained above:

Code Snippet
  1. // Declare delegate — defines required signature:
  2. delegate double MathAction(double num);
  3. class DelegateTest
  4. {
  5.     // Regular method that matches signature:    
  6.     static double Double(double input)
  7.     { return input * 2; }
  8.  
  9.     static void Main()
  10.     {
  11.         // Instantiate delegate with named method:     
  12.         MathAction ma = Double;
  13.         // Invoke delegate ma:       
  14.         double multByTwo = ma(4.5);
  15.         Console.WriteLine(multByTwo);
  16.         // Instantiate delegate with anonymous method:  
  17.         MathAction ma2 = delegate(double input)
  18.         { return input * input; };
  19.  
  20.         double square = ma2(5);
  21.         Console.WriteLine(square);
  22.         // Instantiate delegate with lambda expression
  23.         MathAction ma3 = s => s * s * s;
  24.         double cube = ma3(4.375); Console.WriteLine(cube);
  25.     }
  26. }

 
Using a delegate allows the programmer to encapsulate a reference to a method inside a delegate object. The delegate object can then be passed to code which can call the referenced method, without having to know at compile time which method will be invoked.

Another Sample of delegate showing how loose coupling can be achieved using delegates.

Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.IO;
  6.  
  7. namespace KishoreDelegate
  8. {
  9.     public class A1
  10.     {
  11.         // Declare a delegate that takes a single string parameter
  12.         // and has no return type.
  13.         public delegate void ADelegate(string str);
  14.  
  15.         public void F1(ADelegate adelobj)
  16.         {
  17.             adelobj("Calling function ClassB::F2() from Class A1");
  18.  
  19.         }
  20.  
  21.     }
  22.  
  23.     public class B
  24.     {
  25.         private static void F2(string str)
  26.         {
  27.             Console.WriteLine(str);
  28.         }
  29.  
  30.         static void Main(string[] args)
  31.         {
  32.             A1.ADelegate delobj = new A1.ADelegate(F2);
  33.             A1 ojba1 = new A1();
  34.             ojba1.F1(delobj);
  35.  
  36.         }
  37.     }
  38. }

 

Delegate Composition:

 

Code Snippet
  1. using System;
  2.  
  3. delegate void MyDelegate(string s);
  4.  
  5. class MyClass
  6. {
  7.     public static void Hello(string s)
  8.     {
  9.         Console.WriteLine("  Hello, {0}!", s);
  10.     }
  11.  
  12.     public static void Goodbye(string s)
  13.     {
  14.         Console.WriteLine("  Goodbye, {0}!", s);
  15.     }
  16.  
  17.     public static void Main()
  18.     {
  19.         MyDelegate a, b, c, d;
  20.  
  21.         // Create the delegate object a that references
  22.         // the method Hello:
  23.         a = new MyDelegate(Hello);
  24.         // Create the delegate object b that references
  25.         // the method Goodbye:
  26.         b = new MyDelegate(Goodbye);
  27.         // The two delegates, a and b, are composed to form c,
  28.         // which calls both methods in order:
  29.         c = a + b;
  30.         // Remove a from the composed delegate, leaving d,
  31.         // which calls only the method Goodbye:
  32.         d = c – a;
  33.  
  34.         Console.WriteLine("Invoking delegate a:");
  35.         a("A");
  36.         Console.WriteLine("Invoking delegate b:");
  37.         b("B");
  38.         Console.WriteLine("Invoking delegate c:");
  39.         c("C");
  40.         Console.WriteLine("Invoking delegate d:");
  41.         d("D");
  42.     }
  43. }

Delegates and Events:

Delegates are ideally suited for use as events — notifications from one component to "listeners" about changes in that component.

Delegates vs. Interfaces:

Delegates and interfaces are similar in that they enable the separation of specification and implementation. Multiple independent authors can produce implementations that are compatible with an interface specification. Similarly, a delegate specifies the signature of a method, and authors can write methods that are compatible with the delegate specification. When should you use interfaces, and when should you use delegates?

Delegates are useful when:

• A single method is being called.

• A class may want to have multiple implementations of the method specification.

• It is desirable to allow using a static method to implement the specification.

• An event-like design pattern is desired (for more information, see the Events Tutorial).

• The caller has no need to know or obtain the object that the method is defined on.

• The provider of the implementation wants to "hand out" the implementation of the specification to only a few select components.

• Easy composition is desired.

Interfaces are useful when:

• The specification defines a set of related methods that will be called.

• A class typically implements the specification only once.

• The caller of the interface wants to cast to or from the interface type to obtain other interfaces or classes.

Some Key Points:

  1. Delegates can be declared either outside a class definition or as part of a class through the use of the delegate keyword.

  2. Delegates have two parts : the delegate declaration and the delegate instance or static method.

  3. If an exception is thrown, the delegate stops processing methods in the invocation list. It does not matter whether or not an exception handler is present.

  4. The keyword delegate and the .NET infrastructure provided by the System.Delegate (all delegate types are derived) and System.Delegate.MulticastDelegate classes.

  5. Delegates are the base of event handling in .NET.

  6. Delegate types are implicitly sealed.

 

EVENTS:

To understand events better, we need to examine the Observer Design pattern which is used in the design of events in .NET. In the Model/View/Controller (MVC) design strategy, Model is subject and View is observer.

Observer Pattern:Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

Use the observer pattern in any of the following situations:

  • When the abstraction has two aspects with one dependent on the other. Encapsulating these aspects in separate objects will increase the chance to reuse them independently.
  • When the subject object doesn’t know exactly how many observer objects it has.
  • When the subject object should be able to notify it’s observer objects without knowing who these objects are.
  • Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
  • Encapsulate the core (or common or engine) components in a Subject abstraction, and the variable (or optional or user interface) components in an Observer hierarchy as shown below.

observer-motivation

Observer

Subject represents the core (or independent or common or engine) abstraction. Observer represents the variable (or dependent or optional or user interface) abstraction. The Subject prompts the Observer objects to do their thing. Each Observer can call back to the Subject as needed.

Define an object that is the “keeper” of the data model and/or business logic (the Subject). Delegate all “view” functionality to decoupled and distinct Observer objects. Observers register themselves with the Subject as they are created. Whenever the Subject changes, it broadcasts to all registered Observers that it has changed, and each Observer queries the Subject for that subset of the Subject’s state that it is responsible for monitoring.

This allows the number and “type” of “view” objects to be configured dynamically, instead of being statically specified at compile-time.

The protocol described above specifies a “pull” interaction model. Instead of the Subject “pushing” what has changed to all Observers, each Observer is responsible for “pulling” its particular “window of interest” from the Subject.

Benefit and Drawback of Observe pattern include:

  • Abstract coupling between subject and observer, each can be extended and reused individually.
  • Dynamic relationship between subject and observer, such relationship can be established at run time. This gives a lot more programming flexibility.
  • Support for broadcast communication. The notification is broadcast automatically to all interested objects that subscribed to it.
  • Unexpected updates. Observes have no knowledge of each other and blind to the cost of changing in subject. With the dynamic relationship between subject and observers, the update dependency can be hard to track down.

The following diagram and code demonstrates the Observer pattern in which registered objects are notified of and updated with a state change.

structure of participants:

observer-structure

Subject :

knows its observers. Any number of Observer objects may observe a subject.

provides an interface for attaching and detaching Observer objects.

Observer :

defines an updating interface for objects that should be notified of changes in a subject.

ConcreteSubject :

stores state of interest to ConcreteObserver objects.

sends a notification to its observers when its state changes.

ConcreteObserver :

maintains a reference to a ConcreteSubject object.

stores state that should stay consistent with the subject’s.

implements the Observer updating interface to keep its state consistent with the subject’s.

Code Snippet
  1. class MainApp
  2. {
  3.     static void Main()
  4.     {
  5.         // Configure Observer pattern
  6.         ConcreteSubject s = new ConcreteSubject();
  7.  
  8.         s.Attach(new ConcreteObserver(s, "X"));
  9.         s.Attach(new ConcreteObserver(s, "Y"));
  10.         s.Attach(new ConcreteObserver(s, "Z"));
  11.  
  12.         // Change subject and notify observers
  13.         s.SubjectState = "ABC";
  14.         s.Notify();
  15.  
  16.         // Wait for user
  17.         Console.Read();
  18.     }
  19. }
  20.  
  21. // "Subject"
  22. abstract class Subject
  23. {
  24.     private ArrayList observers = new ArrayList();
  25.  
  26.     public void Attach(Observer observer)
  27.     {
  28.         observers.Add(observer);
  29.     }
  30.  
  31.     public void Detach(Observer observer)
  32.     {
  33.         observers.Remove(observer);
  34.     }
  35.  
  36.     public void Notify()
  37.     {
  38.         foreach (Observer o in observers)
  39.         {
  40.             o.Update();
  41.         }
  42.     }
  43. }
  44.  
  45. // "ConcreteSubject"
  46. class ConcreteSubject : Subject
  47. {
  48.     private string subjectState;
  49.  
  50.     // Property
  51.     public string SubjectState
  52.     {
  53.         get { return subjectState; }
  54.         set { subjectState = value; }
  55.     }
  56. }
  57.  
  58. // "Observer"
  59. abstract class Observer
  60. {
  61.     public abstract void Update();
  62. }
  63.  
  64. // "ConcreteObserver"
  65. class ConcreteObserver : Observer
  66. {
  67.     private string name;
  68.     private string observerState;
  69.     private ConcreteSubject subject;
  70.  
  71.     // Constructor
  72.     public ConcreteObserver(
  73.       ConcreteSubject subject, string name)
  74.     {
  75.         this.subject = subject;
  76.         this.name = name;
  77.     }
  78.  
  79.     public override void Update()
  80.     {
  81.         observerState = subject.SubjectState;
  82.         Console.WriteLine("Observer {0}'s new state is {1}",
  83.           name, observerState);
  84.     }
  85.  
  86.     // Property
  87.     public ConcreteSubject Subject
  88.     {
  89.         get { return subject; }
  90.         set { subject = value; }
  91.     }
  92. }

Events & Delegates in .NET

  • Event Handlers in the .NET Framework return void and take two parameters.
  • The first parameter is the source of the event; that is the publishing object.
  • The second parameter is an object derived from EventArgs.
  • Events are properties of the class publishing the event.
  • The keyword event controls how the event property is accessed by the subscribing classes.

An event handler in C# is a delegate with a special signature, given below.

public delegate void MyEventHandler(object sender, MyEventArgs e);

The first parameter (sender) in the above declaration specifies the object that fired the event. The second parameter (e) of the above declaration holds data that can be used in the event handler. The class MyEventArgs is derived from the class EventArgs. EventArgs is the base class of more specialized classes, like MouseEventArgs, ListChangedEventArgs, etc. For GUI event, you can use objects of these specialized EventArgs classes without creating your own specialized EventArgs classes.

In case of event handler, the delegate object is referenced using the key word event as follows

public event MyEventHandler MyEvent;
 

Now, we will set up two classes to see how this event handling mechanism works in .Net framework. The step 2 in the discussion of delegates requires that we define methods with the exact same signature as that of the delegate declaration. In our example, class A will provide event handlers (methods with the same signature as that of the delegate declaration). It will create the delegate objects (step 3 in the discussion of delegates) and hook up the event handler. Class A will then pass the delegate objects to class B. When an event occurs in Class B, it will execute the event handler method in Class A.

Following is the sample code demonstrating events.

Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. namespace EventsHelloWorld
  7. {
  8.     public class myeventargs : EventArgs
  9.     {
  10.         public string str;
  11.     }
  12.  
  13.     //To declare an event inside a class, first a delegate type for the event must be declared,
  14.     //if none is already declared. The delegate type defines the set of arguments that are passed
  15.     //to the method that handles the event. Multiple events can share the same delegate type,
  16.     //so this step is only necessary if no suitable delegate type has already been declared.
  17.  
  18.         
  19.     //Create delegate object
  20.     //1st parameter: specifies the object that fired the event
  21.     //2nd arameter: holds data that can be used in the event handler
  22.     public delegate void mydelegate(object obj, myeventargs e);
  23.  
  24.     class A
  25.     {
  26.         //Create event handler methods
  27.         public void myfunction1(object obj, myeventargs e)
  28.         {
  29.             Console.WriteLine("Hello World {0}", e.str);
  30.         }
  31.  
  32.         //create delegates, plug in the handler and register with the object that will fire the events
  33.         //Hooking up to an event:   From outside the class that declared it, an event looks like a field,
  34.         //but access to that field is very restricted. The only things that can be done are:
  35.         //Compose a new delegate onto that field & Remove a delegate from a (possibly composite) field.
  36.  
  37.         public A(B b)
  38.         {
  39.             //To begin receiving event invocations, client code first creates a delegate of the event type
  40.             //that refers to the method that should be invoked from the event.
  41.             //Then it composes that delegate onto any other delegates that the event might be connected to using +=.
  42.             b.event1 += new mydelegate(myfunction1);
  43.         }
  44.  
  45.     }
  46.  
  47.     //Calls the encapsulated methods through the delegates (fires events)
  48.     class B
  49.     {
  50.         //The event itself is declared. An event is declared like a field of delegate type,
  51.         //except that the keyword event precedes the event declaration, following the modifiers.
  52.         public event mydelegate event1;
  53.  
  54.         public void fireevent(myeventargs eventargs)
  55.         {
  56.             //Once a class has declared an event, it can treat that event just like a field of the
  57.             //indicated delegate type. The field will either be null, if no client has hooked up
  58.             //a delegate to the event, or else it refers to a delegate that should be called when the event is invoked.
  59.             if (event1 != null)
  60.             {
  61.                 //Invoking an event is generally done by first checking for null and then calling the event.
  62.                 //Invoking an event can only be done from within the class that declared the event.
  63.                 event1(this, eventargs);
  64.             }
  65.         }
  66.  
  67.     }
  68.  
  69.     class Program
  70.     {
  71.         static void Main(string[] args)
  72.         {
  73.             myeventargs args1 = new myeventargs();
  74.             args1.str = "!!! Kishore";
  75.             B b = new B();
  76.             A a = new A(b);
  77.  
  78.             b.fireevent(args1);
  79.         }
  80.     }
  81. }
 

An event is a message sent by an object to signal the occurrence of an action. The action could be caused by user interaction, such as a mouse click, or it could be triggered by some other program logic. The object that raises (triggers) the event is called the event sender. The object that captures the event and responds to it is called the event receiver.

In event communication, the event sender class does not know which object or method will receive (handle) the events it raises. What is needed is an intermediary (or pointer-like mechanism) between the source and the receiver. The .NET Framework defines a special type (Delegate) that provides the functionality of a function pointer.

A delegate is a class that can hold a reference to a method. Unlike other classes, a delegate class has a signature, and it can hold references only to methods that match its signature. A delegate is thus equivalent to a type-safe function pointer or a callback. While delegates have other uses, the discussion here focuses on the event handling functionality of delegates. The following example shows an event delegate declaration.

Event delegates are multicast, which means that they can hold references to more than one event handling method. Delegates allow for flexibility and fine-grain control in event handling. A delegate acts as an event dispatcher for the class that raises the event by maintaining a list of registered event handlers for the event.

Introduction to Multi Binding and Multi value converter using IMultiValueConverter & MultiBinding

For Introduction to Value Converters, see the post here.

For more information on mode property, see the the post on mode here.

MultiBinding allows us to bind a binding target property to a list of source properties and then apply logic to produce a value with the given inputs. This example demonstrates how to use MultiBinding. The following example produces a TextBox that adds the numbers in TextBox1 and TextBox2 and puts the result into TextBox3. Here we have two source properties and the one target property. When you enter numbers in the TextBox1 and TextBox2 , the converter comes into play and automatically adds them and puts the result into TextBox3. The values of the Mode and UpdateSourceTrigger properties determine the functionality of the MultiBinding and are used as the default values for all the bindings in the collection unless an individual binding overrides these properties. For example, if the Mode property on the MultiBinding object is set to TwoWay, then all the bindings in the collection are considered TwoWay unless you set a different Mode value on one of the bindings explicitly.

In the following code, AddConverter implements the IMultiValueConverter interface. AddConverter takes the values from the individual bindings and stores them in the values object array. The order in which the Binding elements appear under the MultiBinding element is the order in which those values are stored in the array.

 

Figure1: Important Classes hierarchy.

Figure2: Binding classes hierarchy

The XAML for the above mentioned logic is as follows.

<Window x:Class="DataConversion.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml&quot;
        Title="MainWindow" Height="350" Width="525"
        xmlns:mylocalXAMLnamespace="clr-namespace:DataConversion">
    <StackPanel>
        <StackPanel.Resources>
            <mylocalXAMLnamespace:AddConverter x:Key="XAMLResourceAddConverter" />
        </StackPanel.Resources>

        <TextBox Name="TextBox1" Text="10"></TextBox>
        <TextBox Name="TextBox2" Text="20"></TextBox>
        <Label Content="Sum of above two values:"></Label>
        <TextBox Name="textBox3">
            <TextBox.Text>
                <MultiBinding Converter="{StaticResource XAMLResourceAddConverter}">
                    <Binding ElementName="TextBox1" Path="Text"/>
                    <Binding ElementName="TextBox2" Path="Text"/>
                </MultiBinding>
            </TextBox.Text>
        </TextBox>
    </StackPanel>
</Window>

 

The MultiBinding tag takes binding as a parameter. See the following C# code that does the binding.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Markup;

namespace DataConversion
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

    }

    public class AddConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            int result = Int32.Parse((string)values[0]) + Int32.Parse((string)values[1]);
            return result.ToString();
        }
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotSupportedException("Cannot convert back");
        }
    }

}

 

You can specify multiple bindings in a MultiBinding object. When you use the MultiBinding object with a converter, it produces a final value for the binding target based on the values of those bindings. For example, color might be computed from red, blue, and green values, which can be values from the same or different binding source objects. When a value moves from the target to the sources, the target property value is translated to a set of values that are fed back into the bindings.

Download the Source Code from here

If it’s a good idea, go ahead and do it. It is much easier to apologize than it is to get permission. Admiral Grace Hopper

Data Binding–Source & Target

WPF Data Binding:

In data binding we establish a connection between the properties of two objects that are interested in binding. Binding means establishing a relationship or forming a bond between two entities. In this relationship, one object is referred to as the source and one object is referred to as the target. In the most typical scenario, your source object is the object that contains your data and your target object is a control that displays that data.

For instance, consider a Employee class with a EmployeeName property. If you want to show the EmployeeName property value in the TextBox UI and have the UI automatically change when the EmployeeName property value changes at run-time, you can bind the TextBox.Text property to the EmployeeName property of the Employee object as shown in the following figure 1.

image    Figure 1: Source & Target Objects in Binding

Download code from my article here.