简体   繁体   中英

Combox Items from Colors Set Selected Item Programmatically WPF

I have a comboBox where items are Colors and I would like to set the default selected items.

For example at runtime I would like to set Red color as the selected item.

How can I achieve this? I tried setting the SelectedItem and SelectedValue but no luck they don't work, I'm new in WPF.

Here's my code.

XAML

<ComboBox x:Name="ComboColor" Width="50" Height="50">
   <ComboBox.ItemTemplate>
      <DataTemplate>
         <StackPanel Orientation="Horizontal">
            <Rectangle Fill="{Binding Name}" Width="16" Height="16" Margin="0,2,5,2" />
            <TextBlock Text="{Binding Name}" />
         </StackPanel>
      </DataTemplate>
   </ComboBox.ItemTemplate>
</ComboBox>

C# Code Behind

public MainWindow()
{
   InitializeComponent();
   ComboColor.ItemsSource = typeof(Colors).GetProperties();
   //not working
   ComboColor.SelectedItem = Colors.Red;
   //not working also
   ComboColor.SelectedValue = Colors.Red;
}

The expression

typeof(Colors).GetProperties()

returns a PropertyInfo[] , not a collection of Color instances.

Add this to turn it into an IEnumerable of Colors:

ComboColor.ItemsSource = typeof(Colors)
    .GetProperties()
    .Select(p => p.GetValue(null));

To use a collection of Colors instead of PropertyInfo in XAML, change the ItemTemplate to this:

<ComboBox.ItemTemplate>
    <DataTemplate>
        <StackPanel Orientation="Horizontal">
            <Rectangle Width="16" Height="16" Margin="0,2,5,2">
                <Rectangle.Fill>
                    <SolidColorBrush Color="{Binding}"/>
                </Rectangle.Fill>
            </Rectangle>
            <TextBlock Text="{Binding}" />
        </StackPanel>
    </DataTemplate>
</ComboBox.ItemTemplate>

The color names will however get lost with this solution, and the ComboBox will only show #AARRGGBB values.


It would perhaps make sense to create your own ColorInfo class

public class ColorInfo
{
    public ColorInfo(PropertyInfo info)
    {
        Name = info.Name;
        Color = (Color)info.GetValue(null);
    }

    public string Name { get; }
    public Color Color { get; }
}

set the ItemsSource like this

ComboColor.ItemsSource = typeof(Colors).GetProperties()
    .Select(p => new ColorInfo(p));

and bind to it with

<Rectangle Width="16" Height="16" Margin="0,2,5,2">
    <Rectangle.Fill>
        <SolidColorBrush Color="{Binding Color}"/>
    </Rectangle.Fill>
</Rectangle>
<TextBlock Text="{Binding Name}" />

With

<ComboBox SelectedValuePath="Name" ...>

you could write

ComboColor.SelectedValue = "Red";

With

<ComboBox SelectedValuePath="Color" ...>

this would work:

ComboColor.SelectedValue = Colors.Red;

You are using reflection to get PropertyInfo instances from all properties in the type Colors . Since the ItemsSource is a collection of type PropertyInfo , you cannot just assign a Color as selected item. In fact, the selected item has to be equal to the corresponding instance in ItemsSource .

To make this work as intended, get the PropertyInfo instance for the color to be selected.

ComboColor.SelectedItem = typeof(Colors).GetProperty(nameof(Colors.Red));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM