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
Advertisements

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.

Collections in .NET

Collection : 

A collection is an object that simply allows you to group other objects. Collections can be strongly typed or weakly typed. Basically if your group of objects is strongly typed, it means that it can contain only objects of a specific type. An advantage when using strongly typed class is that when you access an item in the collection, the type of that item is known, and no additional casting needs to be done.  On the other hand, weakly typed collections object can contain objects of any type.

There are different collection namespaces and collection classes in .NET and it is easy for anyone to get confused by the host of collections available in the .NET Framework.

System.Collections:  This Original Collections: System.Collections namespace are largely considered deprecated by developers and by Microsoft itself. In fact they indicate that for the most part you should always favor the generic or concurrent collections. The System.Collections namespace contains interfaces and classes that define various collections of objects, such as lists, queues, bit arrays, hash tables and dictionaries.  In general, the these collections are non-type-safe and in some cases less performing than their generic counterparts.
System.Collections.Concurrent:  The System.Collections.Concurrent namespace provides several thread-safe collection classes that should be used in place of the corresponding types in the System.Collections and System.Collections.Generic namespaces whenever multiple threads are accessing the collection concurrently. 
System.Collections.Generic:  The System.Collections.Generic namespace contains interfaces and classes that define generic collections, which allow users to create strongly typed collections that provide better type safety and performance than non-generic strongly typed collections. 
System.Collections.ObjectModel:  The System.Collections.ObjectModel namespace contains classes that can be used as collections in the object model of a reusable library. Use these classes when properties or methods return collections. 
System.Collections.Specialized:  The System.Collections.Specialized namespace contains specialized and strongly-typed collections; for example, a linked list dictionary, a bit vector, and collections that contain only strings.

Some of the collection classes frequently used are:

Dictionary: Best for high performance lookups.
SortedDictionary: Compromise of Dictionary speed and ordering, uses binary search tree.
SortedList : Very similar to SortedDictionary, except tree is implemented in an array, so has faster lookup on preloaded data, but slower loads.
List : Best for smaller lists where direct access required and no ordering.
LinkedList : Best for lists where inserting/deleting in middle is common and no direct access required.
HashSet : Unique unordered collection, like a Dictionary except key and value are same object.
SortedSet : Unique ordered collection, like SortedDictionary except key and value are same object.
Stack : Essentially same as List<T> except only process as LIFO
Queue : Essentially same as List<T> except only process as FIFO

System.Collections namespace

Weakly typed collections: summary

ArrayList: An array of contiguous indexed elements whose size can be increased dynamically at run time as required. You can use this data structure to store any types of data like integers, strings, structures, objects
  => A dynamic, contiguous collection of objects.
  => Easy to work with, provides basic collection functionality and can easily be converted to an Array.
  => Favor the generic collection List<T> instead.
Hashtable: Represents a collection of key/value pair elements stored based on the hash code of the key.
  => Associative, unordered collection of key-value pairs of objects.
  => Provides high performance access to items in the key-value pair collection, by a specific key.
  => Favor the generic collection Dictionary<TKey,TValue> instead.
Queue : Represents the data structure of first-in-first-out (FIFO).
  => First-in-first-out (FIFO) collection of objects.
  => Favor the generic collection Queue<T> instead.
SortedList : Represents a list of key/value pair elements, sorted by keys and can be accessed by key and by index.
  => Associative, ordered collection of key-value pairs of objects.
  => Provides access to items in the collection by a specific key or an index.
  => Favor the generic collection SortedList<T> instead.
Stack : Represents the data structure of last-in-first-out (LIFO).
  => Last-in-first-out (LIFO) collection of objects.
  => Favor the generic collection Stack<T> instead.

ArrayList Class:

You would expect the ArrayList is pretty much the same as the Array class, but the major differences are that ArrayList is not strongly typed and the ArrayList’s size can be changed dynamically. ArrayList is weakly typed, so in fact you could add any object to the ArrayList even if the type does not match the type of the objects already in the ArrayList.

The big advantage of an ArrayList is that you don’t need to know in advance how many items you want it to contain. A nice method of the ArrayList is the ToArray function, which is often used to build arrays without knowing in advance how many items they will contain. When you call the ToArray function you need to use type of the items you want to be in the array, as a parameter.

Hashtable Class:

A Hashtable class is a weakly typed collection of key-value pairs. This means that for each object you add to the Hashtable, you need to provide a key that uniquely identifies the object. The Hashtable lets you quickly get an object out of the collection by using it’s key. So why is this collection called a Hashtable? Well, what happens when you add a key with a corresponding object is that of the key object, the hash value is calculated. The hash value is a numeric value that can uniquely identify the key object. So the key object is not stored in the collection, only it’s hash value. To get an item out of your Hashtable, again you use the key object to retrieve it:

You can use the Hashtable if you want to access items in your weakly typed collection, based on a key, not on an index.

Queue Class:

Queue class is available for you in the System.Collections namespace. With the Queue class in .NET you can create weakly typed collections that are ordered by the order they are added to the collection. The mechanism here is FIFO: first in first out.

The use of the Queue class is rather limited. Only in special cases for example when you need to accept messages and process them in the order they arrived, the Queue class can be used.

SortedList Class

The SortedList class is a combination of the Array and the Hashtable. You can access items in a SortedList by the index (like the Array), or by the key (like the Hashtable). Like the name insinuates, a SortedList is sorted. But be aware that it’s sorted based on the key object! The index sequence is based on the sort sequence. Also be aware that a SortedList is generally slower than the Hashtable, due to the sorting. The SortedList class is, like the Hashtable, weakly typed. You can retrieve objects form a SortedList by an index, or by the key. Interesting method of the SortedList class is the GetKey(index), this will retrieve the key object for the item at the specified index. The other way around is the IndexOfKey(key) method. This method gets you the index of the object that is coupled with the specified key.

SortedList are useful if you need a collection of which you can access the items, based on either the key or index. Additional, the items are sorted based on the key value. Be aware that these additional functionalities come at a price performance wise. If you only need a collection based on a key-value pair, and you don’t need to be able to access to items based on the index, you’d better use the Hashtable class.

Stack Class

The Stack class is a weakly typed collection. The last object added to the stack is returned as first. This mechanism here is called LIFO: last in first out. The method that is used to add items to the Stack is Push. Like the Queue class, items in a Stack can’t be accessed directly. To get the last added item of the stack, you have can call the Pop or Peek method. The difference between them is that the Peek method just gets the last object of the stack, the Pop method also get the last object and them removes that item from the stack.

You can use it when you have to implement a LIFO mechanism.

Strongly typed collections:

Array Class: Predefined size, used for passing data around.

One of the most basic collection classes is the Array class. In fact it’s not really a collection class, due to its limitations and its not even located in the System.Collections namespace, but in the System namespace. It is strongly typed. The most important thing about the Array is that it has a fixed size, so when you declare an array, you need to specify the number of items you want to contain. Arrays can have multiple dimensions, to create matrix-like structures.

So when can you use an Array? Pretty obviously, when you know in advance how many items your collection contains and you do not expect much extra functionality like sorting or searching. Arrays are often used when passing a number of objects of the same type to a method or function call as a parameter. By using an Array, you don’t have to worry about the fact that your custom build strongly typed collection needs to be known at the receiving side of the call.

CollectionBase Class:Abstract base for building your own collection classes.

The abstract CollectionBase class provides the base class for a custom strongly typed collection. Because the the class is strongly typed, you can access it’s items without casting them to the right type, so no more CType’s or implicit castings.

DictionaryBase Class: Abstract base for building your own collection classes using a key-value pair.

Well, the CollectionBase class is build upon an Arraylist that is stored internally. The DictionaryBase class uses internally a Hashtable to store items of the collection. But the goal of the DictionaryBase class resembles the goal of the Collectionbase class, they both serve as an abstract base for building your own custom strongly typed collection classes.

For example in a DictionaryBase implementation or Hashtable it’s easy to lookup specific items based on a key, while you only can access items in an ArrayList by using an index. So when choosing the way you want to group your objects, you first have to think about what you want to do with your objects.

 

System.Collections.Generic namespace:

The System.Collections.Generic namespace contains interfaces and classes that define generic collections, which allow users to create strongly typed collections that provide better type safety and performance than non-generic strongly typed collections.

A generic collection is strongly typed (type safe), meaning that you can only put one type of object into it.  This eliminates type mismatches at runtime. Another benefit of type safety is that performance is better with value type objects because they don’t incur overhead of being converted to and from type object. With generic collections, you have the best of all worlds because they are strongly typed, like arrays, and you have the additional functionality, like ArrayList and other non-generic collections, without the problems.

Generics were added to version 2.0 of the C# language and the common language runtime (CLR). Generics introduce the concept of type parameters, which make it possible to design classes and methods that defer the specification of one or more types until the class or method is declared and instantiated by client code. Generic classes and methods combine reusability, type safety and efficiency  in a way that their non-generic counterparts cannot. Generics are most frequently used with collections and the methods that operate on them. Version 2.0 of the .NET Framework class library provides a new namespace, System.Collections.Generic, which contains several new generic-based collection classes.

System.Collections.Generic classes:

•Comparer<T> :  Provides a base class for implementations of the IComparer<T> generic interface. 
•Dictionary<TKey, TValue> :  Represents a collection of keys and values. 
•Dictionary<TKey, TValue>.KeyCollection  Represents the collection of keys in a Dictionary<TKey, TValue>. This class cannot be inherited. 
•Dictionary<TKey, TValue>.ValueCollection  Represents the collection of values in a Dictionary<TKey, TValue>. This class cannot be inherited. 
•EqualityComparer<T> :  Provides a base class for implementations of the IEqualityComparer<T> : generic interface. 
•HashSet<T> :  Represents a set of values. 
•KeyedByTypeCollection<TItem> :  Provides a collection whose items are types that serve as keys. 
KeyNotFoundException  The exception that is thrown when the key specified for accessing an element in a collection does not match any key in the collection. 
•LinkedList<T> :  Represents a doubly linked list. 
•LinkedListNode<T> :  Represents a node in a LinkedList<T>. This class cannot be inherited. 
•List<T> :  Represents a strongly typed list of objects that can be accessed by index. Provides methods to search, sort, and manipulate lists. 
•Queue<T> :  Represents a first-in, first-out collection of objects. 
•SortedDictionary<TKey, TValue> :  Represents a collection of key/value pairs that are sorted on the key. 
•SortedDictionary<TKey, TValue>.KeyCollection  Represents the collection of keys in a SortedDictionary<TKey, TValue>. This class cannot be inherited. 
•SortedDictionary<TKey, TValue>.ValueCollection  Represents the collection of values in a SortedDictionary<TKey, TValue>. This class cannot be inherited 
•SortedList<TKey, TValue> :  Represents a collection of key/value pairs that are sorted by key based on the associated IComparer<T> implementation. 
•SortedSet<T> :  Represents a collection of objects that is maintained in sorted order. 
•Stack<T> :  Represents a variable size last-in-first-out (LIFO) collection of instances of the same arbitrary type. 
•SynchronizedCollection<T> :  Provides a thread-safe collection that contains objects of a type specified by the generic parameter as elements. 
•SynchronizedKeyedCollection<K, T> :  Provides a thread-safe collection that contains objects of a type specified by a generic parameter and that are grouped by keys. 
•SynchronizedReadOnlyCollection<T> :  Provides a thread-safe, read-only collection that contains objects of a type specified by the generic parameter as elements.

System.Collections.Generic Interface:

•ICollection<T>  Defines methods to manipulate generic collections. 
•IComparer<T>  Defines a method that a type implements to compare two objects.
•IDictionary<TKey, TValue>  Represents a generic collection of key/value pairs. 
•IEnumerable<T>  Exposes the enumerator, which supports a simple iteration over a collection of a specified type. 
•IEnumerator<T>  Supports a simple iteration over a generic collection. 
•IEqualityComparer<T>  Defines methods to support the comparison of objects for equality. 
•IList<T>  Represents a collection of objects that can be individually accessed by index.  It Provides behavior to add, remove, and index items in a list of objects. Also, this interface defines members to determine whether the implementing collection type is read-only and/or a fixed-size container
•ISet<T>  Provides the base interface for the abstraction of sets.

System.Collections.Concurrent namespace:

The Concurrent Collections: The concurrent collections are new as of .NET 4.0 and are included in the System.Collections.Concurrent namespace. These collections are optimized for use in situations where multi-threaded read and write access of a collection is desired.
The concurrent queue, stack, and dictionary work much as you’d expect. The bag and blocking collection are more unique.

The System.Collections.Concurrent namespace provides several thread-safe collection classes that should be used in place of the corresponding types in the System.Collections and System.Collections.Generic namespaces whenever multiple threads are accessing the collection concurrently.

Below is the summary of each.
•ConcurrentBag<T>  Represents a thread-safe, unordered collection of objects.  Optimized for situations where a thread may be bother reader and writer. 
•ConcurrentDictionary<TKey, TValue>  Represents a thread-safe collection of key-value pairs that can be accessed by multiple threads concurrently. Optimized for multiple readers (allows multiple readers under same lock).
•ConcurrentQueue<T>  Represents a thread-safe first in-first out (FIFO) collection.
•ConcurrentStack<T>  Represents a thread-safe last in-first out (LIFO) collection. 
•OrderablePartitioner<TSource>  Represents a particular manner of splitting an orderable data source into multiple partitions. 
•Partitioner  Provides common partitioning strategies for arrays, lists, and enumerables. 
•Partitioner<TSource>  Represents a particular manner of splitting a data source into multiple partitions.  
•BlockingCollection<T>  Provides blocking and bounding capabilities for thread-safe collections that implement IProducerConsumerCollection<T>. Wrapper collection that implement producers & consumers paradigm. Readers can block until items are available to read. Writers can block until space is available to write (if bounded).

 

System.Collections.Specialized namespace:

BitVector32: A simple structure that stores Boolean values and small integers in 32 bits of memory.
CollectionsUtil: Creates collections that ignore the case in strings.
HybridDictionary: Implements IDictionary by using a ListDictionary while the collection is small, and then switching to a Hashtable when the collection gets large.
ListDictionary: Implements IDictionary using a singly linked list. Recommended for collections that typically contain ten items or fewer.
NameValueCollection: Represents a sorted collection of associated String keys and String values that can be accessed either with the key or with the index.
StringCollection: Represents a collection of strings.
StringDictionary: Implements a hashtable with the key strongly typed to be a string rather than an object.
StringEnumerator: Supports a simple iteration over a StringCollection.

Introduction to MEF Programming – Importing Multiple Objects

Importing Multiple Objects

In the previous blog, we discussed the basic MEF attributes. Let us get into advance topics in MEF step by step.

In the previous example, we wrote the code for the main exe, contract library and MEF Part1. Imagine we have another class derived from IGreeting and implements the SayHelloWorld() function. The class diagram and sequence diagram is shown below.

image

Fig: Class diagram of the participating classes.

image

Fig: Sequence Diagram for the above classes

In the previous blog, i posted the code of all the participating classes. Let us add the new UserGreetingClass to the solution.

Coding the MEFPart2 Library:

  1. Add a New Project –> Visual C# –> Class Library.Enter Name as  MEFPart2. Click OK. Add the following code.
  2. Add a reference to the System.ComponentModel.Composition assembly.
  3. Add a reference to the ContractsLibrary.DLL assembly.
  4. Add the following using statement:
    • using System.ComponentModel.Composition; This allows us to specify the attributes for using MEF.
    • using ContractsLibrary;
  5. Add the following code.
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel.Composition;
  4. using ContractsLibrary;
  5.  
  6. namespace MefLabPart2
  7. {
  8.     [Export(typeof(IGreeting))]
  9.     public class UserGreeting : IGreeting
  10.     {
  11.         public string SayHelloWorld()
  12.         {
  13.             return "Hello " + Environment.UserDomainName;
  14.         }
  15.     }
  16. }

 

Compile the solution and copy the  MEFPart2.DLL to the MainExe\bin\Debug folder, where the MainExe.exe is located. Try running the application. The following error mesage comes up in the console.

The composition remains unchanged. The changes were rejected because of the following error(s): The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.

1) More than one export was found that matches the constraint ‘((exportDefinition.ContractName == "ContractsLibrary.IGreeting") AndAlso (exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") AndAlso "ContractsLibrary.IGreeting".Equals
(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))’.

Resulting in: Cannot set import ‘meflab1.Program.Greetings (ContractName="ContractsLibrary.IGreeting")’ on part ‘meflab1.Program’. Element: meflab1.Program.Greetings (ContractName="ContractsLibrary.IGreeting") –>  meflab1.Program

Press any key to continue . . .

The issue here is that the catalog contains two exports and the import is importing only one export. So when the container tries to match the imports and exports, it fails with the above error.

image

Fig: Debug information of the catalog.

The Import attribute will only be successfully composed when it matches one and only one export. Other cases will produce a composition error. An ordinary ImportAttribute attribute is filled by one and only one ExportAttribute. If more than one is available, the composition engine produces an error. To import more than one export that matches the same contract, use the ImportMany attribute. Imports marked with this attribute are always optional. For example, composition will not fail if no matching exports are present. The following class imports any number of exports of type IGreeting.

  1. class Program
  2. {
  3.     [ImportMany]
  4.     public IEnumerable<IGreeting> Greetings { get; set; }

 

Following is the code of the MainExe project.

using System; 
using System.IO; 
using System.Reflection; 
using System.ComponentModel.Composition; 
using System.ComponentModel.Composition.Hosting; 
//using System.ComponentModel.Composition.Primitives; 
using ContractsLibrary; 
using System.Collections.Generic; 
  
  
  
namespace meflab1 
{ 
    class Program 
    { 
      [ImportMany] 
      public IEnumerable<IGreeting> Greetings { get; set; } 
  
        static void Main(string[] args) 
        { 
            Program program = new Program(); 
            program.Run(); 
        } 
  
        public Program() 
        { 
            try 
            { 
                AggregateCatalog aggregatecatalogue = new AggregateCatalog(); 
                aggregatecatalogue.Catalogs.Add(new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory)); 
                CompositionContainer container = new CompositionContainer(aggregatecatalogue); 
                CompositionBatch batch = new CompositionBatch(); 
                batch.AddPart(this); 
                container.Compose(batch); 
            } 
            catch (FileNotFoundException fnfex) 
            { 
                Console.WriteLine(fnfex.Message); 
            } 
            catch (CompositionException cex) 
            { 
                Console.WriteLine(cex.Message); 
            } 
        } 
  
        void Run() 
        { 
            foreach (var mgreeting in Greetings) 
            { 
                if (mgreeting != null) 
                { 
                    Console.WriteLine(mgreeting.SayHelloWorld()); 
                    Console.ReadKey(); 
                } 
            } 
        } 
    } 
} 

 

Source Code is available at :

Microsoft: http://cid-38ecce05b21b8b44.office.live.com/self.aspx/MY%20Projects/mef%202.zip

(OR) Google: MEF Lab 2 (http://code.google.com/p/mef-dotnet/downloads/detail?name=mef%202.zip)

Have Fun !!!

 “If your actions inspire others to dream more, learn more, do more and become more, you are a leader.”