Friday, May 26, 2017

WPF MultiValueConverter

In the previous Topic WPF ValueConverters we discuss that how Convertor manipulate the Source type value to Target Type value and Vice versa, but if instead of one value we have multiple values to convert in binding.

when you need to bind multiple value in a control and need some manipulation then we need Multivalue convertrer.

Consider a scenario, we need to show the full name of user which is input in three different textboxes "First Name", "Middle Name" and "Last Name".


\
Code for xaml file "MainWindows.xaml"

<Window x:Class="WpftricksMultiValueConverter.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:multivalueConverter="clr-namespace:WpftricksMultiValueConverter"
        Title="wpftricks" Height="259.211" Width="600">
    <Window.Resources>
        <multivalueConverter:ConcateMultiValueConverter x:Key="concateMultiValueConverter" />
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="0.5*"/>
            <ColumnDefinition Width="1*"/>
        </Grid.ColumnDefinitions>
        <Label Grid.Row="0" Content="First Name" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="10" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"/>

        <TextBox Grid.Row="0" Grid.Column="1" Text="{Binding FirstName, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="10" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"/>

        <Label Grid.Row="1" Content="Middle Name" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="10" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"/>

        <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding MiddleName, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="10" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"/>

        <Label Grid.Row="2" Content="Last Name" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="10" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"/>

        <TextBox Grid.Row="2" Grid.Column="1" Text="{Binding LastName, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="10" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"/>

        <Label Grid.Row="3" Grid.ColumnSpan="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0"
                   VerticalContentAlignment="Center" HorizontalContentAlignment="Center">
            <Label.Content>
                <MultiBinding Converter="{StaticResource concateMultiValueConverter}">
                    <Binding Path="FirstName" />
                    <Binding Path="MiddleName" />
                    <Binding Path="LastName" />
                </MultiBinding>
            </Label.Content>
        </Label>

    </Grid>
</Window>

 Code for ViewModel "ViewModel.cs"


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WpftricksMultiValueConverter
{
    public class ViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private string firstName;
        public string FirstName
        {
            get { return firstName; }
            set
            {
                firstName = value;
                NotifyPropertyChanged("FirstName");
            }
        }

        private string middleName;
        public string MiddleName
        {
            get { return middleName; }
            set
            {
                middleName = value;
                NotifyPropertyChanged("MiddleName");
            }
        }

        private string lastName;
        public string LastName
        {
            get { return lastName; }
            set
            {
                lastName = value;
                NotifyPropertyChanged("LastName");
            }
        }
        public void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

    }
}


 Code for MultiValueConverter "ConcateMultiValueConverter.cs"

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;

namespace WpftricksMultiValueConverter
{
    public class ConcateMultiValueConverter : IMultiValueConverter
    {

        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            string firstName = values[0] as string;
            string middleName = values[1] as string;
            string lastName = values[2] as string;
           
            return firstName + " " + middleName + " " + lastName;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

here you can see Convert function have parameter object array "values", in which we can receive multi binding value to do some manipulation.