Posted by: Zeeshan Amjad | November 19, 2014

Convert Event to Command using Blend SDK


We saw an example of how to change the controls event into command using attached dependency property here and here. Microsoft Expression Blend SDK provide another simple way to do this.

The first step is to include the reference of System.Windows.Interactivity.dll. On 64 bit Windows, it can be find in the following location.

C:\Program Files (x86)\Microsoft SDKs\Expression\Blend\.NETFramework\v4.5\Libraries

or

C:\Program Files (x86)\Microsoft SDKs\Expression\Blend\.NETFramework\v4.0\Libraries

Lets make a simple example of ListBox and convert the SelectionChanged event into command. At first step Let’s create a ViewModel. The ViewModel contains the ObservableCollection to populate the Listbox, SelectedItem property to store the currently selected item and SelectedCommand property.

Code Snippet
    public class CitiesViewModel : ViewModelBase
    {
        private ObservableCollection<string> _cities;
        private string _selectedItem;

        public CitiesViewModel()
        {
            Cities = new ObservableCollection<string>
            { "Boston", "Los Angeles", "Houston", "New York", "Chicago", "Philadelphia" };

            SelectedItemCommand = new DelegateCommand<string>(SelectionChange, () => true);
        }

        private void SelectionChange(string value)
        {
            SelectedItem = value;
        }

        public ObservableCollection<string> Cities
        {
            get { return _cities; }
            set
            {
                if (Equals(value, _cities)) return;
                _cities = value;
                OnPropertyChanged();
            }
        }

        public string SelectedItem
        {
            get { return _selectedItem; }
            set
            {
                if (value == _selectedItem) return;
                _selectedItem = value;
                OnPropertyChanged();
            }
        }

        public ICommand SelectedItemCommand
        {
            get; set;
        }
    }

 

Now first include the reference of System.Windows.Interactivity in XAML.

Code Snippet
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

 

Here is a XAML code to use expression interactivity to convert SelectionChanged event into command and bind it with SelectedItemCommand defined in CitiesViewModel. In addition it also passes the SelectedItem as a command parameter.

Code Snippet
<i:Interaction.Triggers>
    <i:EventTrigger EventName="SelectionChanged">
        <i:InvokeCommandAction Command="{Binding SelectedItemCommand}"
            CommandParameter="{Binding Path=SelectedItem, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}}"/>
    </i:EventTrigger>
</i:Interaction.Triggers>

 

Here is complete XAML code of the program.

Code Snippet
<Window x:Class="IntractivitySample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml&quot;
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008&quot;
        xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
        Title="Event Trigger" Height="300" Width="400">
    <Grid DataContext="{Binding}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <ListBox Grid.Column="0" Margin="5" HorizontalContentAlignment="Stretch" ItemsSource="{Binding Cities}">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="SelectionChanged">
                    <i:InvokeCommandAction Command="{Binding SelectedItemCommand}"
                        CommandParameter="{Binding Path=SelectedItem, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>

        </ListBox>
        <TextBlock Grid.Column="1" Margin="5" Text="{Binding SelectedItem}"/>
    </Grid>
</Window>

 

And here is complete C# code of the program.

Code Snippet
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Input;

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

            DataContext = new CitiesViewModel();
        }
    }

    public class DelegateCommand<T> : ICommand
    {
        private Action<T> _action;
        private Func<bool> _predicate;

        public DelegateCommand(Action<T> _action, Func<bool> _predicate)
        {
            this._action = _action;
            this._predicate = _predicate;
        }

        private void Execute(T parameter)
        {
            if (_action != null)
            {
                _action(parameter);
            }
        }

        public bool CanExecute(object parameter)
        {
            if (_predicate != null)
            {
                return _predicate();
            }

            return true;
        }

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

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

    public class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }        
    }
    public class CitiesViewModel : ViewModelBase
    {
        private ObservableCollection<string> _cities;
        private string _selectedItem;

        public CitiesViewModel()
        {
            Cities = new ObservableCollection<string>
            { "Boston", "Los Angeles", "Houston", "New York", "Chicago", "Philadelphia" };

            SelectedItemCommand = new DelegateCommand<string>(SelectionChange, () => true);
        }

        private void SelectionChange(string value)
        {
            SelectedItem = value;
        }

        public ObservableCollection<string> Cities
        {
            get { return _cities; }
            set
            {
                if (Equals(value, _cities)) return;
                _cities = value;
                OnPropertyChanged();
            }
        }

        public string SelectedItem
        {
            get { return _selectedItem; }
            set
            {
                if (value == _selectedItem) return;
                _selectedItem = value;
                OnPropertyChanged();
            }
        }

        public ICommand SelectedItemCommand
        {
            get; set;
        }
    }
}

 

And this is the output of the program.

EventTrigger

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s

Categories

%d bloggers like this: