locked
ColorPicker in Win 8.1

    General discussion

  • I'm porting an app from Windows 7/C#/XAML to Windows 8.1/C#/XAML Store App. In the Windows 7 version, there was a hand-rolled Color Picker. The user would click a dropdown, and a small grid would appear filled with different colored boxes. The user would click the box representing the color they wanted, and that would be used for subsequent operations.

    I starting porting this, then realized there's no way a user on a tablet is going to be able to select from among small boxes to pick a color with his finger.

    What are people using for a Color Picker in a Windows 8.1 tablet app? I'm trying to stay away from third party controls for now. If there's a C#/XAML hand-rolled picker that works, a pointer would be great.

    Thanks...


    Randy


    Monday, March 17, 2014 7:50 PM

All replies

  • What do you mean by "third party controls" as opposed to a "hand-rolled picker"?

    There are free third party toolkits which include color pickers. Depending on what exactly you need it's also not hard to create your own, especially if you just need to expose existing color swatches and not full RGB or HSL editing.

    --Rob

    Monday, March 17, 2014 8:09 PM
    Owner
  • In this context, "third party controls" means go spend money. "Hand-rolled picker" means gets some pointers and write one myself.

    I only need to allow the user to select from among a few unique colors. Having the whole color spectrum is not required.

    My preference would be to get some pointers/suggestions and just write one.

    Thanks!


    Randy

    Monday, March 17, 2014 8:32 PM
  • I came up with the following: A class called PreferencesColor that defines a List of colors, and also a DisplayColor property. I bind to PreferencesColor in XAML from a ComboBox, and the background of the selected item gets painted the selected color. Great! There's still a couple of things needed:

    • Convert the list from the hex value (#FFFF0000) to the name (Red).
    • Possibly make the background of everything in the List the color is represents (I could live without this part).

    Here's the source code:

    namespace TestColorComboBox
    {
        public class PreferencesColor : INotifyPropertyChanged
        {
            private string displayColor = Colors.Red.ToString();
            private List<string> colorList = new List<string>
            { 
                Colors.Red.ToString(), 
                Colors.Green.ToString(), 
                Colors.Blue.ToString(), 
                Colors.Yellow.ToString(), 
                Colors.Orange.ToString() 
            };
    
            public string DisplayColor
            {
                get
                {
                    return displayColor;
                }
                set
                {
                    if (!Equals(displayColor, value))
                    {
                        displayColor = value;
                        OnPropertyChanged("DisplayColor");
                    }
                }
            }
    
    
    
            public List<string> ColorList
            {
                get { return colorList; }
                set
                {
                    if (!Equals(colorList, value))
                    {
                        colorList = value;
                        OnPropertyChanged("ColorList");
                    }
                }
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            private void OnPropertyChanged(string p)
            {
                if (PropertyChanged != null)
                {
                    PropertyChangedEventArgs eventArgs =
                        new PropertyChangedEventArgs(p);
                    PropertyChanged(this, eventArgs);
                }
            }
        }
    }
    

    <Page
        x:Class="TestColorComboBox.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:TestColorComboBox"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
        <Page.DataContext>
            <local:PreferencesColor />
        </Page.DataContext>
    
        <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
            <ComboBox x:Name="cboColorPicker"
                SelectedValue="{Binding Path=DisplayColor}"
                ItemsSource="{Binding Path=ColorList}"
                Background="{Binding ElementName=cboColorPicker, Path=SelectedValue}"
                HorizontalAlignment="Left" Margin="225,238,0,0" VerticalAlignment="Top" Width="120"/>
    
        </Grid>
    </Page>
    


    Randy

    Tuesday, March 18, 2014 5:43 PM
  • I've tried many different approaches, including the creation of a separate ComboBoxItem for each ComboBox item where the Background is set. Some of this worked in Windows 7, but none of it works in Windows 8.1 Store App.

    The fact that programmers cannot create a dropdown where each item is represented only by a background color is a bug in Windows 8.1. I'm hoping that someone at Microsoft will see this and write it up. This needs to be fixed quickly.


    Randy

    Thursday, April 03, 2014 5:28 PM
  • The fact that programmers cannot create a dropdown where each item is represented only by a background color is a bug in Windows 8.1.

    In what way is this not possible? Customised UI controls are one of the strengths of Xaml. Take a look at the colour swatches I mention in my blog entry Accessibility Gotchas 2: High Contrast. The data templates I included in that post and should be easy for you to adapt.

    There are also several free third party controls you might consider if you aren't stuck on rolling your own.

    --Rob

    Thursday, April 03, 2014 5:44 PM
    Owner
  • I created several test projects, and one included a custom ComboBox. You can get the background color for each item to be Red, Green, Blue, etc., but when you mouse over to select/click, the background color gives way to the selection color (black text on white background). Further, once the selection is complete, you get black text on white background. This is very confusing to the user: "Every time I pick a color it turns white, so I don't know what's happening."

    As far as I can find, there's no properties exposed by the framework to allow the selection color to be the item background color in a ComboBox. There's a number of threads in different places on the web where people asked this same question and never sorted it out for Windows 8 (though there are threads where people got this working for Windows 7). I have no doubt this would be easy to do with panels, but it seems to not be an option with ComboBoxes.

    If someone has insights on getting this working in the context of a ComboBox, I'd love to hear about it. I claim this is pretty basic functionality that many people will need, and that Microsoft should pitch in with a flag or property that would make this doable.


    Randy

    Thursday, April 03, 2014 7:13 PM
  • I just copied my template into a ComboBox and it works just fine. The selection color and mouse-over highlight color appears around the border swatch (for the normal contrast version) but don't override it where the border has colour. Since the template sets the text and background colours you don't get black text on white background (except for the "White" colour swatch, of course). The colour swatch and text both stay consistent.

    --Rob

    Thursday, April 03, 2014 9:54 PM
    Owner
  • Any chance you could post the code?

    Randy

    Friday, April 04, 2014 11:40 AM
  • The Xaml's in the blog entry. I can post the data object when I get into the office, but it's pretty straightforward: a Color property returning a Brush and a Name property returning a string. The ContrastConverter checks the color's brightness and returns a black or white brush, but you can remove that for testing purposes.
    Friday, April 04, 2014 2:32 PM
    Owner
  • Please do post when you get in. Thanks!

    Randy

    Friday, April 04, 2014 3:04 PM
  • Here some code-behind to go with the Xaml from the blog:

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.IO;
    using System.Linq;
    using System.Runtime.InteropServices.WindowsRuntime;
    using Windows.Foundation;
    using Windows.Foundation.Collections;
    using Windows.UI;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Data;
    using Windows.UI.Xaml.Input;
    using Windows.UI.Xaml.Media;
    using Windows.UI.Xaml.Navigation;
    using System.Reflection;
    using System.Diagnostics;
    
    // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
    
    namespace InaccessibleGrid
    {
        class ColorData
        {
            public ColorData(String name, Color color)
            {
                this.Name = name;
                this.Color = color;
            }
            public string Name { get; private set; }
            public Color Color { get; private set; }
    
            public string UniqueId { get { return Name + ": " + Color.ToString(); } }
            public string AccName { get { return ToString(); } }
    
            public override string ToString() { return this.UniqueId; }
        }
    
        /// <summary>
        /// An empty page that can be used on its own or navigated to within a Frame.
        /// </summary>
        public sealed partial class MainPage : Page
        {
            ObservableCollection<ColorData> model;
            public MainPage()
            {
                this.InitializeComponent();
    
                model = new ObservableCollection<ColorData>();
                foreach (var prop in typeof(Colors).GetRuntimeProperties())
                {
                    model.Add(new ColorData(prop.Name, (Color)prop.GetValue(null)));
                }
                this.DataContext = model;
            }
        }
    
    
        public class ContrastConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, string language)
            {
                Color c = (Color)value;
    
                double Y = 0.3 * c.R + 0.59 * c.G + 0.11 * c.B;
    
                return Y < 0.5 ? App.Current.Resources["LightBrush"] : App.Current.Resources["DarkBrush"];
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, string language)
            {
                throw new NotImplementedException();
            }
        }
    
    }
    

    Saturday, April 05, 2014 2:24 AM
    Owner
  • Thanks for replying at 2:24 am on a Saturday. I believe the following quote describes why I'm not seeing this work:

    Since the template sets the text and background colours you don't get black text on white background (except for the "White" colour swatch, of course). The colour swatch and text both stay consistent."

    The question becomes: How do I set the ItemsTemplate property of the ComboBox to use the data template? The error I'm getting is: The resource "Default" could not be resolved. I'm including your ResourceDictionary code incase I somehow got that wrong.

    Thanks...

    <Page.Resources>
        <local:ColorToBrushConverter x:Key="colorToBrushConverter" />
        <local:ContrastConverter x:Key="contrastConverter" />
    
        <ResourceDictionary x:Key="MyResourceDictionary">
            <ResourceDictionary.ThemeDictionaries>
                <ResourceDictionary x:Key="Default">
                    <DataTemplate x:Key="ColorListTemplate">
                        <Grid>
                            <Border BorderThickness="4" Height="100" Width="400" HorizontalAlignment="Center" VerticalAlignment="Center" >
                                <Border.Background>
                                    <SolidColorBrush Color="{Binding Color}"/>
                                </Border.Background>
                                <TextBlock 
                    Text="{Binding Name}"  VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="{Binding Color, Converter={StaticResource contrastConverter}}"/>
                            </Border>
                        </Grid>
                    </DataTemplate>
                </ResourceDictionary>
                <ResourceDictionary x:Key="HighContrast">
                    <DataTemplate x:Key="ColorListTemplate">
                        <Grid>
                            <Border BorderThickness="4" Height="100" Width="400" HorizontalAlignment="Center" VerticalAlignment="Center" >
                                <Border.BorderBrush>
                                    <SolidColorBrush Color="{Binding Color}"/>
                                </Border.BorderBrush>
                                <TextBlock Text="{Binding Name}"  VerticalAlignment="Center" HorizontalAlignment="Center"/>
                            </Border>
                        </Grid>
                    </DataTemplate>
                </ResourceDictionary>
            </ResourceDictionary.ThemeDictionaries>
        </ResourceDictionary>
    </Page.Resources>
        
    
    <StackPanel>
        <ComboBox x:Name="cboColorPicker2"
            ItemsSource="{Binding model}"
            ItemTemplate="{Binding RelativeSource={ThemeResource Default}}"
            DisplayMemberPath="Name"
            SelectedValuePath="Color"
            HorizontalAlignment="Left" Margin="225,238,0,0" VerticalAlignment="Top" Width="120"/>
    </StackPanel>


    Randy

    Monday, April 07, 2014 1:49 PM
  • This still does not work. Please, either post a complete code example, or tell me you don't want to help. Posting incomplete code examples has caused me to waste far too much time.

    <Page.Resources>
        <local:ColorToBrushConverter x:Key="colorToBrushConverter" />
        <local:ContrastConverter x:Key="contrastConverter" />
    
        <DataTemplate x:Key="ColorListTemplate">
            <Grid>
                <Border BorderThickness="4" Height="100" Width="400" HorizontalAlignment="Center" VerticalAlignment="Center" >
                    <Border.Background>
                        <SolidColorBrush Color="{Binding Color}"/>
                    </Border.Background>
                    <TextBlock 
                    Text="{Binding Name}"  VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="{Binding Color, Converter={StaticResource contrastConverter}}"/>
                </Border>
            </Grid>
        </DataTemplate>
    </Page.Resources>
    
    <StackPanel>
        <ComboBox x:Name="cboColorPicker2"
            DisplayMemberPath="Name"
            SelectedValuePath="Color"
            ItemTemplate="{Binding Path=ColorListTemplate}"
            HorizontalAlignment="Left" Margin="225,238,0,0" VerticalAlignment="Top" Width="120">
        </ComboBox>
    </StackPanel>
    public sealed partial class MainPage : Page
    {
        ObservableCollection<ColorData> _colorDataCollection;
    
        public MainPage()
        {
            this.InitializeComponent();
    
            _colorDataCollection = new ObservableCollection<ColorData>();
            foreach (var prop in typeof(Colors).GetRuntimeProperties())
            {
                _colorDataCollection.Add(new ColorData(prop.Name, (Color)prop.GetValue(null)));
            }
            //this.DataContext = _colorDataCollection;
    
    
            ComboBoxItem redcbi = new ComboBoxItem();
            redcbi.Foreground = new SolidColorBrush(Colors.Red);
            redcbi.BorderBrush = new SolidColorBrush(Colors.Red);
            redcbi.BorderThickness = new Thickness(3);
            redcbi.Content = "Red";
            cboColorPicker2.Items.Add(redcbi);
    
            ComboBoxItem greencbi = new ComboBoxItem();
            greencbi.Foreground = new SolidColorBrush(Colors.Green);
            greencbi.BorderBrush = new SolidColorBrush(Colors.Green);
            greencbi.BorderThickness = new Thickness(3);
            greencbi.Content = "Green";
            cboColorPicker2.Items.Add(greencbi);
    
            ComboBoxItem bluecbi = new ComboBoxItem();
            bluecbi.Foreground = new SolidColorBrush(Colors.Blue);
            bluecbi.BorderBrush = new SolidColorBrush(Colors.Blue);
            bluecbi.BorderThickness = new Thickness(3);
            bluecbi.Content = "Blue";
            cboColorPicker2.Items.Add(bluecbi);
    
    
        }
    
        public ObservableCollection<ColorData> ColorDataCollection
        {
            get { return _colorDataCollection; }
            set { _colorDataCollection = value; }
        }
    
    }

    public class ColorData
    {
        public ColorData(String name, Color color)
        {
            this.Name = name;
            this.Color = color;
        }
        public string Name { get; private set; }
        public Color Color { get; private set; }
    
        public string UniqueId { get { return Name + ": " + Color.ToString(); } }
        public string AccName { get { return ToString(); } }
    
        public override string ToString() { return this.UniqueId; }
    
    }



    Randy

    Tuesday, April 08, 2014 1:12 PM
  • Hi Randy,

    If you need individual support please open a support case at http://aka.ms/storesupport . The forums are community based support. I and my team are happy to help out if you post clear and polite questions, but we cannot write your code for you or provide turnkey custom controls.

    That said, you can hook up a ComboBox to the template I provided as follows. The name of the template is "ColorListTemplate". "Default" and "HighContrast" are the names of the resource dictionaries the template will be picked from in normal and in high contrast modes, respectively.

            <ComboBox Grid.Column="0" Height="50" ItemTemplate="{ThemeResource ColorListTemplate}" ItemsSource="{Binding}">
    
            </ComboBox>

    The problem with your second code snippet is that you removed the databinding and bypassed the template in favour of explicit ComboBoxItems that don't do what you want.

    More reading:
    Quickstart: Data binding to controls (the example used is a ComboBox)

    Quickstart: Styling controls
    Quickstart: Control templates
    Specifying the look of the items (relevant to any collection control, not just lists and grids)

    --Rob

    Tuesday, April 08, 2014 11:38 PM
    Owner
  • Rob,

    I followed your instructions, and again, it does not work. With the ComboBox declared exactly as you provided, I’m getting the following error:

    A first chance exception of type 'Windows.UI.Xaml.Markup.XamlParseException' occurred in TestColorComboBox.exe

    WinRT information: Cannot find a Resource with the Name/Key ColorListTemplate [Line: 52 "line-height:normal;margin-bottom:0pt;">

    I’ll post my code below. Again, I’m working with Visual Studio 2013 in a Windows Store Application on Windows 8.1.

    From your last post:

    I and my team are happy to help out if you post clear and polite questions, but we cannot write your code for you or provide turnkey custom controls.

    This thread has been going off-and-on for 3 weeks, and I continue to get incomplete/misleading answers that have caused me to waste many hours. Rather than continue on that path, I asked if you would simply post the code you claim is working on your box. Twisting that into the claim that I’m asking you to write code for me is a cheap shot and is uncalled for. I found a thread on the “Bing Maps for Windows Store apps” forum, where someone asked for dashed MapPolylines. Even though that’s not supported, a Microsoft employee provided code showing how to do this:

    http://social.msdn.microsoft.com/Forums/en-US/7f54034f-4e16-47fa-ad88-b94f2dbba269/dashed-line-for-polygons?forum=bingmapswindows8

    I just asking for an example that shows binding from a ComboBox to a DataTemplate that actually works.

    Can we make nice here?

    <Page
        x:Class="TestColorComboBox.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:TestColorComboBox"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Page.Resources>
            <local:ColorToBrushConverter x:Key="colorToBrushConverter" />
            <local:ContrastConverter x:Key="contrastConverter" />
    
            <ResourceDictionary x:Key="MyResourceDictionary">
                <ResourceDictionary.ThemeDictionaries>
                    <ResourceDictionary x:Key="Default">
                        <DataTemplate x:Key="ColorListTemplate">
                            <Grid>
                                <Border BorderThickness="4" Height="100" Width="400" HorizontalAlignment="Center" VerticalAlignment="Center" >
                                    <Border.Background>
                                        <SolidColorBrush Color="{Binding Color}"/>
                                    </Border.Background>
                                    <TextBlock 
                    Text="{Binding Name}"  VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="{Binding Color, Converter={StaticResource contrastConverter}}"/>
                                </Border>
                            </Grid>
                        </DataTemplate>
                    </ResourceDictionary>
                    <ResourceDictionary x:Key="HighContrast">
                        <DataTemplate x:Key="ColorListTemplate">
                            <Grid>
                                <Border BorderThickness="4" Height="100" Width="400" HorizontalAlignment="Center" VerticalAlignment="Center" >
                                    <Border.BorderBrush>
                                        <SolidColorBrush Color="{Binding Color}"/>
                                    </Border.BorderBrush>
                                    <TextBlock Text="{Binding Name}"  VerticalAlignment="Center" HorizontalAlignment="Center"/>
                                </Border>
                            </Grid>
                        </DataTemplate>
                    </ResourceDictionary>
                </ResourceDictionary.ThemeDictionaries>
            </ResourceDictionary>
        </Page.Resources>
    
    
        <StackPanel>
            <ComboBox x:Name="cboColorPicker2"
                ItemTemplate="{ThemeResource ColorListTemplate}"
                ItemsSource="{Binding}"
                HorizontalAlignment="Left" Margin="225,238,0,0" VerticalAlignment="Top" Width="120">
            </ComboBox>
    
        </StackPanel>
    </Page>

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.IO;
    using System.Linq;
    using System.Runtime.InteropServices.WindowsRuntime;
    using Windows.Foundation;
    using Windows.Foundation.Collections;
    using Windows.UI;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Data;
    using Windows.UI.Xaml.Input;
    using Windows.UI.Xaml.Media;
    using Windows.UI.Xaml.Navigation;
    
    using System.Reflection;
    
    // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
    
    namespace TestColorComboBox
    {
        /// <summary>
        /// An empty page that can be used on its own or navigated to within a Frame.
        /// </summary>
        public sealed partial class MainPage : Page
        {
            ObservableCollection<ColorData> _colorDataCollection;
    
            public MainPage()
            {
                this.InitializeComponent();
    
                _colorDataCollection = new ObservableCollection<ColorData>();
                foreach (var prop in typeof(Colors).GetRuntimeProperties())
                {
                    _colorDataCollection.Add(new ColorData(prop.Name, (Color)prop.GetValue(null)));
                }
                this.DataContext = _colorDataCollection;
            }
        }
    }
    


    Randy

    Wednesday, April 09, 2014 12:23 PM
  • NOTE: I ended up not using the code below. I was able to save the user's last setting before application shutdown, but was not able to load that last setting when the application was restarted (I had no problem reloading ComboBoxes that did not use a DataTemplate). It seems like this would be a trivial thing, and if somebody would like to share how to do this, it would be appreciated.

    ////////////////////////////////////////////////////////////////////////

    With help from this and other resources, I finally figured this out. I'm still not seeing how to put my DataTemplate into a ResourceDictionary and access it from my ComboBox, but hopefully, someone will pitch in on that.

    I debugged this by putting the DataTemplate inside the ComboBox, and moving the DataTemplate to the Page.Resources section only after getting the pieces working. The last piece was to get the contractConverter right, since the original example used App.Current.Resources that I could not find.

    ContrastConverter.cs:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Windows.UI;
    using Windows.UI.Xaml.Data;
    using Windows.UI.Xaml.Media;
    
    namespace TestColorComboBox
    {
        public class ContrastConverter : IValueConverter
        {
            SolidColorBrush _lightBrush = null;
            SolidColorBrush _darkBrush = null;
    
            public ContrastConverter()
            {
                _lightBrush = new SolidColorBrush(Colors.White);
                _darkBrush = new SolidColorBrush(Colors.Black);
            }
    
            object IValueConverter.Convert(object value, Type targetType, object parameter, string language)
            {
                Color c = (Color)value;
    
                //double Y = 0.3 * c.R + 0.59 * c.G + 0.11 * c.B;
    
                // 255 * 3 = 765
                double Y = c.R + c.G + c.B;
    
                //return Y < 0.5 ? App.Current.Resources["LightBrush"] : App.Current.Resources["DarkBrush"];
                // Use the light brush for only the darkest colors.
                return Y < 300.0 ? _lightBrush : _darkBrush;
    
            }
    
            object IValueConverter.ConvertBack(object value, Type targetType, object parameter, string language)
            {
                throw new NotImplementedException();
            }
        }
    }

    ColorData.cs:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Windows.UI;
    
    namespace TestColorComboBox
    {
    public class ColorData
    {
        private Color _color = new Color();
        public ColorData(String name, Color color)
        {
            this.Name = name;
            this.Color = color;
        }
        public string Name { get; private set; }
        public Color Color
        {
            get
            {
                return _color;
            }
            private set
            {
                _color = value;
            }
        }
    
        public string UniqueId { get { return Name + ": " + Color.ToString(); } }
        public string AccName { get { return ToString(); } }
    
        public override string ToString() { return this.UniqueId; }
    
    }
    }

    MainPage.xaml.cs:

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.IO;
    using System.Linq;
    using System.Runtime.InteropServices.WindowsRuntime;
    using Windows.Foundation;
    using Windows.Foundation.Collections;
    using Windows.UI;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Data;
    using Windows.UI.Xaml.Input;
    using Windows.UI.Xaml.Media;
    using Windows.UI.Xaml.Navigation;
    
    using System.Reflection;
    
    namespace TestColorComboBox
    {
        /// <summary>
        /// An empty page that can be used on its own or navigated to within a Frame.
        /// </summary>
        public sealed partial class MainPage : Page
        {
            ObservableCollection<ColorData> _colorDataCollection;
    
            public MainPage()
            {
                this.InitializeComponent();
    
                _colorDataCollection = new ObservableCollection<ColorData>();
                foreach (var prop in typeof(Colors).GetRuntimeProperties())
                {
                    _colorDataCollection.Add(new ColorData(prop.Name, (Color)prop.GetValue(null)));
                }
    
                this.DataContext = _colorDataCollection;
            }
        }
    }

    MainPage.xaml

    <Page
        x:Class="TestColorComboBox.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:TestColorComboBox"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Page.Resources>
            <local:ColorToBrushConverter x:Key="colorToBrushConverter" />
            <local:ContrastConverter x:Key="contrastConverter" />
    
            <DataTemplate x:Name="ColorItemsForComboBox">
                <Grid Width="200">
                    <Border BorderThickness="4" Height="50" Width="200" HorizontalAlignment="Left" VerticalAlignment="Center" >
                        <Border.Background>
                            <SolidColorBrush Color="{Binding Color}"/>
                        </Border.Background>
                        <TextBlock 
                    Text="{Binding Name}"  VerticalAlignment="Center" HorizontalAlignment="Left" 
                            Foreground="{Binding Color, Converter={StaticResource contrastConverter}}"/>
                    </Border>
                </Grid>
            </DataTemplate>
        </Page.Resources>
    
    
        <StackPanel>
            <ComboBox x:Name="cboColorPicker2"
                ItemsSource="{Binding}"
                ItemTemplate="{StaticResource ColorItemsForComboBox}"
                HorizontalAlignment="Left" Margin="225,238,0,0" VerticalAlignment="Top" Width="200">
            </ComboBox>
        </StackPanel>
    </Page>


    Randy


    • Edited by Randy42Developer42 Thursday, April 10, 2014 2:27 PM Added warning about posted code.
    Wednesday, April 09, 2014 1:35 PM