Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Styling WPF ComboBox items

I have a very simple WPF application which displays a ComboBox which binds to a list of classes which represent people. Each 'Person' object has a Name string field, and a Sex enum. I would like the ComboBox to display a drop-down of the various people's Name field, but for each line to be styled according to the Sex field, for example, blue for males, pink for females. Can anyone tell me what I am doing wrong?

Here is the XML:

<Window x:Class="ComboBoxColour.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel Orientation="Vertical">
        <ComboBox ItemsSource="{Binding People}" Width="100" Height="20">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Name="somePerson" Text="{Binding Path=Name}">                        
                        <TextBlock.Triggers>
                            <DataTrigger Binding="{Binding Path=Sex}" Value="Male">
                                <DataTrigger.Setters>
                                    <Setter Property="Foreground" Value="Blue" TargetName="somePerson" />
                                </DataTrigger.Setters>
                            </DataTrigger>
                        </TextBlock.Triggers>                        
                    </TextBlock>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
    </StackPanel>
</Window>

And here is the C#:

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.Collections.ObjectModel;

namespace ComboBoxColour
{
  /// <summary>
  /// Interaction logic for MainWindow.xaml
  /// </summary>
  public partial class MainWindow : Window
  {
    public List<Person> people;
    public List<Person> People
    {
      get { return people; }
      set { people = value; }
    }

    public MainWindow()
    {
      this.DataContext = this;

      People = new List<Person>();
      People.Add(new Person("Alice", SexEnum.Female));
      People.Add(new Person("Bob", SexEnum.Male));
      People.Add(new Person("Claire", SexEnum.Female));
      People.Add(new Person("Daniel", SexEnum.Male));

      InitializeComponent();
    }
  }

  public enum SexEnum{Male,Female};

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

    private SexEnum sex;
    public SexEnum Sex
    {
      get { return sex; }
      set { sex = value; }
    }

    public Person(string Name, SexEnum Sex)
    {
      this.Name = Name;
      this.Sex = Sex;
    }
  }
}

Many thanks in advance

like image 623
JamesPD Avatar asked Jan 05 '12 16:01

JamesPD


2 Answers

Use ItemContainerStyle instead of ItemTemplate:

    <ComboBox ItemsSource="{Binding People}" Width="100" Height="20">
        <ComboBox.ItemContainerStyle>
            <Style TargetType="ComboBoxItem">
                <Setter Property="Foreground" Value="Pink" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Path=Sex}" Value="Male">
                        <Setter Property="Foreground" Value="Blue" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ComboBox.ItemContainerStyle>
    </ComboBox>
like image 126
Thomas Levesque Avatar answered Nov 13 '22 05:11

Thomas Levesque


You should use "Style" triggers instead of "TextBlock.Triggers"

use this XAML:

<Window x:Class="ComboBoxColour.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel Orientation="Vertical">
        <ComboBox ItemsSource="{Binding People}" Width="100" Height="20">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Name="somePerson" Text="{Binding Path=Name}">
                        <TextBlock.Style>
                            <Style TargetType="TextBlock">
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding Path=Sex}" Value="Male">
                                        <DataTrigger.Setters>
                                            <Setter Property="Foreground" Value="blue"/>
                                        </DataTrigger.Setters>
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding Path=Sex}" Value="Female">
                                        <DataTrigger.Setters>
                                            <Setter Property="Foreground" Value="Pink"/>
                                        </DataTrigger.Setters>
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </TextBlock.Style>
                    </TextBlock>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
    </StackPanel>
</Window>

Now you'll have blue for male and pink for female.

like image 37
Seffix Avatar answered Nov 13 '22 05:11

Seffix