WPF ComboBox Colors


This post is a sample program of a ComboBox that lists all of the WPF system colors. It is a “color picker”, or a “color viewer”. The user can pick a color from the list and set the background, similar to how they might do to set preferences or options. This post is loosely based on some code over at C# Helper. I have made many changes. The great thing about this approach is that we don’t need to manually add all these colors. We use Reflection to get the list of system colors and load the list upon the Window_Loaded event. We have a very similar program here that uses a ListBox instead of a ComboBox.

What’s next? We have a follow-up post called WPF ComboBox Colors with SQLite that takes his example project and adds a SQLite database that remembers the color you picked even if you close the program and open it again. The color index is stored in a SQLite database with Dapper.

Below is the XAML.

<Window x:Class="DropDownColorsInWPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DropDownColorsInWPF"
        mc:Ignorable="d"
        WindowStartupLocation="CenterScreen"
        Title="DropDownColorsInWPF" Height="350" Width="400"
        Loaded="Window_Loaded">
    <Grid Margin="6">
        <Grid.RowDefinitions>
            <RowDefinition Height="20"/>
            <RowDefinition Height="20"/>
            <RowDefinition Height="25"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <TextBlock Name="txtblkTitle" Grid.Row="0">Based on code from C# Helper website.</TextBlock>
        <TextBlock Name="txtblkRGBNumbers" Grid.Row="1">RGB</TextBlock>
        <TextBlock Name="txtblkDescription" Grid.Row="3" TextWrapping="Wrap">Change the color of the background 
            of the title with the drop-down selector.</TextBlock>
        <ComboBox Grid.Row="2" Name="cboboxColors" ScrollViewer.CanContentScroll="True" 
                 ScrollViewer.VerticalScrollBarVisibility="Auto" 
                 SelectionChanged="CboboxColors_SelectionChanged">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal" Margin="0,3,0,0">
                        <StackPanel.Resources>
                            <Style TargetType="TextBlock">
                                <Setter Property="Margin" Value="5,0,0,0"/>
                            </Style>
                        </StackPanel.Resources>
                        <Rectangle Width="30" Fill="{Binding SampleBrush}"/>
                        <TextBlock Name="ColorOfItem" Width="130" Text="{Binding ColorName}"/>
                        <TextBlock Width="70" Text="{Binding HexValue}"/>
                    </StackPanel>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
    </Grid>
</Window>

Below is the C# code.

using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace DropDownColorsInWPF
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        // List samples of the named colors.
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            var color_query = from PropertyInfo property in typeof(Colors).GetProperties()
                              orderby property.Name
                              //orderby ((Color)property.GetValue(null, null)).ToString()
                              select new ColorInfo(
                                      property.Name,
                                      (Color)property.GetValue(null, null));

            cboboxColors.ItemsSource = color_query;
        }
        private void CboboxColors_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ComboBox cb = sender as ComboBox;

            // change the background of the second row (second TextBox)
            txtblkRGBNumbers.Background = new SolidColorBrush(Color.FromRgb((cb.SelectedItem as ColorInfo).Color.R,
                (cb.SelectedItem as ColorInfo).Color.G, (cb.SelectedItem as ColorInfo).Color.B));
            // txtblkDescription
            txtblkDescription.Background = new SolidColorBrush(Color.FromArgb(128,
                  (cb.SelectedItem as ColorInfo).Color.R,
                  (cb.SelectedItem as ColorInfo).Color.G, 
                  (cb.SelectedItem as ColorInfo).Color.B));

            // display the RBG and A of the selected color
            object ci = cb.SelectedItem;
            txtblkRGBNumbers.Text = (cb.SelectedItem as ColorInfo).ColorName +
                    " is Red " + (ci as ColorInfo).Color.R +
                    "     Green " + (ci as ColorInfo).Color.G +
                    "     Blue " + (ci as ColorInfo).Color.B +
                    "     Alpha " + (ci as ColorInfo).Color.A;

        }
    }
    // Used to display color name, RGB value, and sample.
    // From C Sharp Helper
    // http://csharphelper.com/blog/2015/10/list-colors-in-wpf-and-c/
    //
    public class ColorInfo
    {
        public string ColorName { get; set; }
        public Color Color { get; set; }

        public SolidColorBrush SampleBrush
        {
            get { return new SolidColorBrush(Color); }
        }
        public string HexValue
        {
            get { return Color.ToString(); }
        }

        public ColorInfo(string color_name, Color color)
        {
            ColorName = color_name;
            Color = color;
        }
    }
}