ToolTip

Today I was trying to reuse xaml of a WPF in Silverlight 5 and came across this difference.
In WPF :
<TextBlock Text="{Binding FirstName}" ToolTip="{Binding FullName}"/>


In Silverlight:
 <TextBlock Text="{Binding FirstName}"> <ToolTipService.ToolTip> <ToolTip Content="{Binding FullName}"/> </ToolTipService.ToolTip> </TextBlock>

Converter

Data Binding is one of the most power propery of WPF. Ex: Binding the background color of the TextBlock to the color that is selected in the ListBox. The following code adds a Background property to the TextBlock and uses the attribute binding syntax to bind to the value of the selected item in the ListBox:

<TextBlock 
    Width="248" 
    Height="24" 
    x:Name="tbSelectedColor" 
    Text="{Binding ElementName=lbColor, Path=SelectedItem.Content,Mode=OneWay}"
    Background="{Binding ElementName=lbColor, Path=SelectedItem.Content,Mode=OneWay}"/>

In this example the a property of type string is our binding source object which is binded to the Color property? If there is a typo in the source object string or if we want to databind two properties that have incompatible types it will stop working.
Converts converter is a user defined class, which implements the IValueConverter interface. IvalueConverter provides a way to apply custom logic to a binding by implementing the Convert and ConvertBack methods. Converters can change data from one type to another, translate data based on cultural information, or modify other aspects of the presentation.

Convert(): The data binding engine calls this method when it propagates a value from the binding source to the binding target. A return value of DependencyProperty.UnsetValue indicates that the converter produced no value and that the binding uses the FallbackValue, if available, or the default value instead.
A return value of Binding.DoNothing indicates that the binding does not transfer the value or use the FallbackValue or default value.

ConvertBack(): The data binding engine calls this method when it propagates a value from the binding target to the binding source.
The implementation of this method must be the inverse of the Convert method.
A return value of DependencyProperty.UnsetValue indicates that the converter produced no value and that the binding uses the FallbackValue, if available, or the default value instead.
A return value of Binding.DoNothing indicates that the binding does not transfer the value or use the FallbackValue or default value.

I came across a requirement where the ListBox Height must change according to the Size of ListBox. In this example there is a ListBox with 10 Items and a Delete button which delete items from the ListBox. As the Item Count changes(here reduces) Height also changes.We can do this using Converters. The Height of the ListBox is binded with the ItemCount. 

xaml
<Window x:Class="WpfConverters.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfConverters"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:WidthConverter x:Key="converter"/>
    </Window.Resources>
    <Grid>
        <ListBox Name="personListBox" ItemsSource="{Binding PersonList}" 
                 Margin="40,8,313,12" Width="150" 
                 Height="{Binding Path=PersonList.Count, Converter={StaticResource converter}}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding Name}"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <Button Content="Delete" Height="23" 
                HorizontalAlignment="Left" Margin="243,41,0,0" 
                Name="DeleteButton" VerticalAlignment="Top" Width="75"
                Command="{Binding DeleteCommand}" CommandParameter="{Binding}"/>
    </Grid>
</Window>


Converter
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Data;
using System.Collections.ObjectModel;

namespace WpfConverters
{
    class WidthConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            var listCount = value as int?;
            if (listCount.HasValue)
            {
                if (listCount == 0)
                    return 10;
                else if (listCount < 2)
                    return 100;
                else if (listCount >= 3)
                    return 200;
                else if (listCount >= 5)
                    return 250;
            }
            return 400;
        }

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


ViewModel
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Windows.Input;

namespace WpfConverters
{
    public class ViewModel : INotifyPropertyChanged
    {
        public ICommand DeleteCommand { get; private set; }
        public ViewModel()
        {
            PersonList = new ObservableCollection<Person>();
            PersonList.Add(cust1);
            PersonList.Add(cust2);
            PersonList.Add(cust3);
            PersonList.Add(cust4);
            PersonList.Add(cust5);
            PersonList.Add(cust6);
            PersonList.Add(cust7);
            PersonList.Add(cust8);
            DeleteCommand = new RelayCommand(ExecuteDeleteCommand, CanExecuteDeleteCommand);
        }

        Person cust1 = new Person() { Name = "Alice", Age = 20 };
        Person cust2 = new Person() { Name = "Bob", Age = 21 };
        Person cust3 = new Person() { Name = "Mark", Age = 22 };
        Person cust4 = new Person() { Name = "Jay", Age = 23 };
        Person cust5 = new Person() { Name = "Mike", Age = 23 };
        Person cust6 = new Person() { Name = "Linda", Age = 22 };
        Person cust7 = new Person() { Name = "Maya", Age = 21 };
        Person cust8 = new Person() { Name = "Susan", Age = 20 };

        ObservableCollection<Person> personList;

        public ObservableCollection<Person> PersonList
        {
            get { return personList; }
            set { personList = value; OnPropertyChanged("PersonList"); }
        }

        public void ExecuteDeleteCommand(object parameter)
        {
            PersonList.Remove(PersonList.LastOrDefault());
        }

        public bool CanExecuteDeleteCommand(object parameter)
        {
            if (personList.Count == 0)
                return false;
            else
                return true;            
        }

        public event PropertyChangedEventHandler PropertyChanged;

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

Model
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WpfConverters
{
   public class Person
    {
        string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        int age;
        public int Age
        {
            get { return age; }
            set { age = value; }
        }
    }
}

Reference:
1. http://msdn.microsoft.com/en-us/magazine/cc163299.aspx
2. http://wpftutorial.net/ValueConverters.html