Applying Control Template on ComboxItems in WPF

In WPF, each and every control has a layout or design that is defined by the template applied to it. This template is known as the ControlTemplate. Every control in WPF by default has a default template applied to it. That's why when you drag and drop a control onto a WPF window you get the default design or layout for that particular control. For example: When a button is dragged and dropped you get the default layout for the button control, something like this:

WPF1.jpg

To see the default template for any of the controls, right-click that control then select "Properties" then go to the style and you can view the default template that is applied to that control in WPF. The following screenshots show that.

WPF2.jpg

WPF3.jpg

Just as how we override methods in programming, in a similar fashion we can override the layout of a control in WPF. Overriding here means changing the visual tree for a particular control of WPF by defining it in our ControlTemplate. Using a control template we all can change or modify the structure and appearance of a particular control. One thing to keep in mind is that when we are modifying the control structure, we have to define the full structure for that particular control, it is not possible to change only a portion of the control by setting its Template property.

Now moving toward our sample, we just try to change the normal display behavior of our comboboxitem by overriding its layout using a ControlTemplate.

The following is the brief description of the code for that. Remember, we are applying a control template using XAML, but the same thing can be done through Code behind also.

The C# class whose data would be displayed on a combobox such as a comboboxItem:

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

namespace WpfApplication1
{
    class PersonList
    {
        public string Name { get; set; }
        public string Address { get; set; }

        public static ObservableCollection<PersonList> GetAllPersons()
        {
            ObservableCollection<PersonList> objPersonList = new ObservableCollection<PersonList>
            {
                new PersonList(){Name="Rahul",Address="Andheri"},
                new PersonList(){Name="Pankaj",Address="Worli"},
                new PersonList(){Name="Jack",Address="Dadar"},
                new PersonList(){Name="Rushi",Address="Churchgate"},
                new PersonList(){Name="Mayur",Address="Thane"}
            };
            return objPersonList;
        }
    }
}

MainWindow.xaml

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Main Window" Height="300" Width
="400">
    <Window.Resources>
        <Style x:Key="comboItemStyle" TargetType="{x:Type ComboBoxItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ComboBoxItem}">
                        <Border BorderThickness="2" BorderBrush="LightBlue" Background="Wheat"
                                MinWidth="200" MinHeight="30" Cursor="Hand" CornerRadius="2" FlowDirection="LeftToRight">
                            <ComboBoxItem MinWidth="100" MinHeight="10" FontFamily="Verdana" FontSize="12"  FlowDirection="LeftToRight"
                                          HorizontalContentAlignment="Left"
                                           VerticalAlignment
="Bottom">
                                <ContentPresenter HorizontalAlignment="Left" VerticalAlignment="Bottom" Height="15" Width="100"/>
                            </ComboBoxItem>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="true">
                                <Setter Property="Foreground" Value="Red"/>
                                <Setter Property="FontWeight" Value="Bold"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Grid>
        <ComboBox Height="36" DisplayMemberPath="Name" HorizontalAlignment="Left" Margin="10,10,0,0"  ItemContainerStyle="{StaticResource comboItemStyle}"
                  Name="comboBox1" VerticalAlignment="Top" Width
="200">
        </ComboBox>
    </Grid>
</
Window>


MainWindow.xaml.cs File

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 WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            comboBox1.ItemsSource = PersonList.GetAllPersons();
        }
    }
}

The output would be rendered as

WPF4.jpg

Hope you all liked the example.