locked
How to add colors to a combobox in metro app? RRS feed

  • Question

  • I want to add a list of colors to a combo box in metro app using C#. In turn, user can choose a particular color from the list to change background color.

    The probable library available is Windows.UI.Colors

    Here is a link to achieve it for a simple Desktop app: http://www.c-sharpcorner.com/uploadfile/mahesh/how-to-load-all-colors-in-a-combobox-using-C-Sharp/

    But I was not able to port it to metro environment.

    Also, both colour name as well as colour itself as a list item would be a huge plus.

    Please help asap...
    Regards,
    √irαl ⌡αiπ

    Sunday, April 8, 2012 1:58 PM

Answers

  • I do something like that with the code below.

    <ComboBox x:Name="cbColorNames" Grid.Row="1" Height="40"
              ItemsSource="{Binding Colors}"
              SelectedItem="{Binding SelectedColorName, Mode=TwoWay}">
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <Grid Background="Black">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <Rectangle Width="35" Height="20" Fill="{Binding Name}" Margin="5,0"/>
                    <TextBlock Grid.Column="1" Margin="10,0,0,0" Text="{Binding Name}" Foreground="White"/>
                </Grid>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>
    private static void LoadColors()
    {
        var t = typeof(Colors);
        var ti = t.GetTypeInfo();
        var dp = ti.DeclaredProperties;
        colors = new List<PropertyInfo>();
        foreach (var item in dp)
        {
            colors.Add(item);
        }
    }
    
    private static List<PropertyInfo> colors;
    public List<PropertyInfo> Colors
    {
        get
        {
            if (colors == null)
                LoadColors();
            return colors;
        }
    }
    


    Sunday, April 8, 2012 10:56 PM
  • This looks correct for a Metro style app.

    You need to include the proper namespaces to use the classes from them. Windows.UI.Colors needs Windows.UI and System.Reflection.PropertyInfo and GetTypeInfo need System.Reflection:

    using Windows.UI;
    using System.Reflection;

    The IDE will help you with this. If you click on the classes with the red squiggly the IDE will show a little blue rectangle under the first letter:

    If you click on that it will bring up a context menu to offer to fix the problem by adding the appropriate references or generating a new class (in your case you want to add the appropriate references)

    • Marked as answer by Viral.Jain Friday, April 13, 2012 8:03 AM
    Thursday, April 12, 2012 8:09 PM
    Moderator
  • If you want to use SelectionChanged it would be something like this. (not tested)

    if (cbColorNames.SelectedIndex != -1)
    {
        var pi = cbColorNames.SelectedItem as PropertyInfo;
        var color = (Color)pi.GetValue(null);
        var scb = new SolidColorBrush(color);
        this.Background = scb;
    }

    • Marked as answer by Viral.Jain Friday, April 13, 2012 6:36 PM
    Friday, April 13, 2012 11:28 AM

All replies

  • I do something like that with the code below.

    <ComboBox x:Name="cbColorNames" Grid.Row="1" Height="40"
              ItemsSource="{Binding Colors}"
              SelectedItem="{Binding SelectedColorName, Mode=TwoWay}">
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <Grid Background="Black">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <Rectangle Width="35" Height="20" Fill="{Binding Name}" Margin="5,0"/>
                    <TextBlock Grid.Column="1" Margin="10,0,0,0" Text="{Binding Name}" Foreground="White"/>
                </Grid>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>
    private static void LoadColors()
    {
        var t = typeof(Colors);
        var ti = t.GetTypeInfo();
        var dp = ti.DeclaredProperties;
        colors = new List<PropertyInfo>();
        foreach (var item in dp)
        {
            colors.Add(item);
        }
    }
    
    private static List<PropertyInfo> colors;
    public List<PropertyInfo> Colors
    {
        get
        {
            if (colors == null)
                LoadColors();
            return colors;
        }
    }
    


    Sunday, April 8, 2012 10:56 PM
  • I do something like that with the code below.

    <ComboBox x:Name="cbColorNames" Grid.Row="1" Height="40"
              ItemsSource="{Binding Colors}"
              SelectedItem="{Binding SelectedColorName, Mode=TwoWay}">
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <Grid Background="Black">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <Rectangle Width="35" Height="20" Fill="{Binding Name}" Margin="5,0"/>
                    <TextBlock Grid.Column="1" Margin="10,0,0,0" Text="{Binding Name}" Foreground="White"/>
                </Grid>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>
    private static void LoadColors()
    {
        var t = typeof(Colors);
        var ti = t.GetTypeInfo();
        var dp = ti.DeclaredProperties;
        colors = new List<PropertyInfo>();
        foreach (var item in dp)
        {
            colors.Add(item);
        }
    }
    
    private static List<PropertyInfo> colors;
    public List<PropertyInfo> Colors
    {
        get
        {
            if (colors == null)
                LoadColors();
            return colors;
        }
    }


    @RBear2, @jpsanders: Is the answer applicable to Metro app? I doubt it.


    These are the errors Sir. Please guide me... :)


    √rl

    Thursday, April 12, 2012 7:04 PM
  • This looks correct for a Metro style app.

    You need to include the proper namespaces to use the classes from them. Windows.UI.Colors needs Windows.UI and System.Reflection.PropertyInfo and GetTypeInfo need System.Reflection:

    using Windows.UI;
    using System.Reflection;

    The IDE will help you with this. If you click on the classes with the red squiggly the IDE will show a little blue rectangle under the first letter:

    If you click on that it will bring up a context menu to offer to fix the problem by adding the appropriate references or generating a new class (in your case you want to add the appropriate references)

    • Marked as answer by Viral.Jain Friday, April 13, 2012 8:03 AM
    Thursday, April 12, 2012 8:09 PM
    Moderator
  • Thanks a lot!!!

    √rl

    Friday, April 13, 2012 8:04 AM
  • @Sir: The code worked, but now how to change background color by choosing the color from combobox.

    Please help me.


    √rl

    Friday, April 13, 2012 9:57 AM
  • If you want to use SelectionChanged it would be something like this. (not tested)

    if (cbColorNames.SelectedIndex != -1)
    {
        var pi = cbColorNames.SelectedItem as PropertyInfo;
        var color = (Color)pi.GetValue(null);
        var scb = new SolidColorBrush(color);
        this.Background = scb;
    }

    • Marked as answer by Viral.Jain Friday, April 13, 2012 6:36 PM
    Friday, April 13, 2012 11:28 AM
  • @RBear2: Sir, you are a saviour!!! It worked.
    Please explain me why we used 'PropertyInfo' & (Color)pi.GetValue(null). I want to know what they really do.
    Please explain me if you can.

    √rl

    Friday, April 13, 2012 6:36 PM
  • Hi, I have just copy pasted your code, but it is not working for me.
    The combo box is not fiiling, even when I click on the corner of combo
    box is is not opening. I am embeding my whole code here. Please help me I
    also need that kind of combo box.

    <Page
        x:Class="Metro_Paint.BlankPage1"
        IsTabStop="false"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:Metro_Paint"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <ComboBox x:Name="cbColorNames" Grid.Row="1" Height="40"
              ItemsSource="{Binding Colors}"
              SelectedItem="{Binding SelectedColorName, Mode=TwoWay}" SelectionChanged="cbColorNames_SelectionChanged_1">
                <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <Grid Background="Black">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="*"/>
                            </Grid.ColumnDefinitions>
                            <Rectangle Width="35" Height="20" Fill="{Binding Name}" Margin="5,0"/>
                            <TextBlock Grid.Column="1" Margin="10,0,0,0" Text="{Binding Name}" Foreground="White"/>
                        </Grid>
                    </DataTemplate>
                </ComboBox.ItemTemplate>
            </ComboBox>
        </Grid>
    </Page>

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    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;
    
    // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
    
    namespace Metro_Paint
    {
        /// <summary>
        /// An empty page that can be used on its own or navigated to within a Frame.
        /// </summary>
        public sealed partial class BlankPage1 : Page
        {
            public BlankPage1()
            {
                this.InitializeComponent();
                LoadColors();
            }
    
            /// <summary>
            /// Invoked when this page is about to be displayed in a Frame.
            /// </summary>
            /// <param name="e">Event data that describes how this page was reached.  The Parameter
            /// property is typically used to configure the page.</param>
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
            }
    
    
    
            private static void LoadColors()
            {
                var t = typeof(Colors);
                var ti = t.GetTypeInfo();
                var dp = ti.DeclaredProperties;
                colors = new List<PropertyInfo>();
                foreach (var item in dp)
                {
                    colors.Add(item);
                }
            }
    
            private static List<PropertyInfo> colors;
            public List<PropertyInfo> Colors
            {
                get
                {
                    if (colors == null)
                        LoadColors();
                    return colors;
                }
            }
    
            private void cbColorNames_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
            {
                if (cbColorNames.SelectedIndex != -1)
                {
                    var pi = cbColorNames.SelectedItem as PropertyInfo;
                    var color = (Color)pi.GetValue(null);
                    var scb = new SolidColorBrush(color);
                    this.Background = scb;
                }
            }
        }
    }
    

    Wednesday, July 4, 2012 7:09 AM
  • public MainPage()
            {
                this.DataContext = this;
                this.InitializeComponent();
            }

    I suggest you add "this.DataContext = this" (see the above code) so that the Binding to the collection of Colors can materialize.

    The "LoadColors();" in your constructor is superfluous since the Colors {get} will lazily instantiate the collection.

    • Edited by ForInfo Wednesday, July 4, 2012 10:43 AM
    • Proposed as answer by Xyroid Wednesday, July 4, 2012 10:51 AM
    Wednesday, July 4, 2012 10:40 AM
  • Thank you ForInfo, It finally worked :)

    I have one more query  if you can solve

    Wednesday, July 4, 2012 10:56 AM
  • Unfortunately not an expert in Ink writing ...
    Wednesday, July 4, 2012 11:00 AM