Search code examples
c#wpflistviewcomboboxobjectdataprovider

WPF ComboBox as System.Windows.Media.Colors


Wanting to get the color combobox (see image) behavior in my WPF ListView column. photo

Can someone help me get this started? I am comfortable with ListView binding but not sure how to implement this.

EDIT:

 xmlns:System="clr-namespace:System;assembly=mscorlib"

<ObjectDataProvider MethodName="GetValues"
                    ObjectType="{x:Type System:Enum}"
                    x:Key="ColorList">
   <ObjectDataProvider.MethodParameters>
       <x:Type TypeName="Windows.Media.Color" />
   </ObjectDataProvider.MethodParameters>
</ObjectDataProvider>

Tells me type provided must be an enum.

Best Answer I have found: How can I list colors in WPF with XAML?


Solution

  • ComboBox with ItemTemplate

    You will have to use ItemTemplate for you ComboBox items:

        <ComboBox ItemsSource="{Binding NamedColors}"
                  xmlns:converters="clr-namespace:TestLab.WPF">
            <ComboBox.Resources>
                <converters:ColorToSolidBrushConverter x:Key="ColorToBrush"/>
            </ComboBox.Resources>
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Border BorderThickness="0" Height="20" Width="20" 
                                Background="{Binding Value, Converter={StaticResource ColorToBrush}}"/>
                        <TextBlock Text="{Binding Key}"/>
                    </StackPanel>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
    

    Brush converter

    Also, you will need a color to brush converter, because binding doesn't do it automatically:

    public class ColorToSolidBrushConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return new SolidColorBrush((Color)value);
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    Color name - color pair creation

    And here is how you can create the color Name - color pairs (currently it is an instance method in the main Window class, but you can refactor it to some helper class):

        private IEnumerable<KeyValuePair<String, Color>> GetColors()
        {
            return typeof(Colors)
                .GetProperties()
                .Where(prop =>
                    typeof(Color).IsAssignableFrom(prop.PropertyType))
                .Select(prop =>
                    new KeyValuePair<String, Color>(prop.Name, (Color)prop.GetValue(null)));
        }
    

    Window code

    And this is the window:

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
    
            this.NamedColors = this.GetColors();
    
            this.DataContext = this;
        }
    
        public IEnumerable<KeyValuePair<String, Color>> NamedColors
        {
            get;
            private set;
        }
    }
    

    ObjectDataProvider

    Some code file:

    public namespace SomeNamespace 
    {
        public static class ColorHelper
        {
            public static IEnumerable<KeyValuePair<String, Color>> GetColors()
            {
                return typeof(Colors)
                    .GetProperties()
                    .Where(prop =>
                        typeof(Color).IsAssignableFrom(prop.PropertyType))
                    .Select(prop =>
                        new KeyValuePair<String, Color>(prop.Name, (Color)prop.GetValue(null)));
            }
        }
    }
    

    XAML object data provider:

    ...
    xmlns:someNamespace="clr-namespace:SomeNamespace"
    ...
    <ObjectDataProvider MethodName="GetColors"
                        ObjectType="{x:Type someNamespace.ColorHelper}"
                        x:Key="ColorList">
    </ObjectDataProvider>
    

    XAML comboBox:

    <ComboBox ItemsSource="{Binding ColorList}" ...