由 Hue 组织的颜色选择框

Posted

技术标签:

【中文标题】由 Hue 组织的颜色选择框【英文标题】:A Color Selection Box Organized by Hue 【发布时间】:2018-06-27 11:57:07 【问题描述】:

下面是一些生成不同颜色分布的代码。 (它将ComboBox 绑定到生成的颜色列表)。

以下代码没问题。

xaml

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>

    <TextBox x:Name="TextBox1"  Width="300" Height="30" VerticalAlignment="Top" />

    <ComboBox Margin="15" Height="30" Width="200" ItemsSource="Binding ColorList" ScrollViewer.HorizontalScrollBarVisibility="Disabled" SelectionChanged="ComboBox_SelectionChanged">

        <ComboBox.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Rectangle Height="55" Width="55" x:Name="Rectangle1">
                        <Rectangle.Fill>
                            <SolidColorBrush Color="Binding Color"/>
                        </Rectangle.Fill>
                    </Rectangle>
                </Grid>
            </DataTemplate>
        </ComboBox.ItemTemplate>

        <ComboBox.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel IsItemsHost="True" Orientation="Horizontal" Width="1000"/>
            </ItemsPanelTemplate>
        </ComboBox.ItemsPanel>

    </ComboBox>

</Grid>
</Window>

C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;

namespace WpfApplication1

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged

    public MainWindow()
    
        this.InitializeComponent();
        this.DataContext = this;

        ColorList = ColorUtil.GenerateColorList(16);
    

    private List<ColorWithInfo> colorList;
    public List<ColorWithInfo> ColorList
    
        get  return colorList; 
        protected set
        
            colorList = value;
            RaisePropertyChanged("ColorList");
        
    

    // INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged = delegate  ;

    private void RaisePropertyChanged(string propName)
    
        PropertyChanged(this, new PropertyChangedEventArgs(propName));
    

    private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    
        TextBox1.Text = "Show Hex color here, for example #0000ff ";
    



public class ColorWithInfo : IComparable

    public Color Color  get; set; 

    public string Info
    
        get  return string.Format("0/1/2", Color.R, Color.G, Color.B); 
    

    public string HueSatBright
    
        get  return string.Format("0/1/2", Hue, Saturation, Brightness); 
    

    public float Hue
    
        get  return System.Drawing.Color.FromArgb(Color.R, Color.G, Color.B).GetHue(); 
    

    public float Saturation
    
        get  return System.Drawing.Color.FromArgb(Color.R, Color.G, Color.B).GetSaturation(); 
    

    public float Brightness
    
        get  return System.Drawing.Color.FromArgb(Color.R, Color.G, Color.B).GetBrightness(); 
    

    public int CompareTo(object obj)
    
        ColorWithInfo cwiOther = obj as ColorWithInfo;

        // Sort by Hue, and then Saturation, and then Brightness
        if (this.Hue == cwiOther.Hue)
        
            if (this.Saturation == cwiOther.Saturation)
                return this.Brightness.CompareTo(cwiOther.Brightness);
            else
                return this.Saturation.CompareTo(cwiOther.Saturation);
        
        else
            return this.Hue.CompareTo(cwiOther.Hue);
    



public static class ColorUtil

    public static List<ColorWithInfo> GenerateColorList(int numValsPerColor)
    
        List<ColorWithInfo> colorList = new List<ColorWithInfo>();

        // Create increment such that we start at 0, end at 255,
        // and have a total of numValsPerColor within that range.
        int delta = Convert.ToInt32(255.0 / ((double)numValsPerColor - 1.0));

        for (int r = 0; r < numValsPerColor; r++)
            for (int g = 0; g < numValsPerColor; g++)
                for (int b = 0; b < numValsPerColor; b++)
                
                    ColorWithInfo cwi = new ColorWithInfo
                    
                        Color = Color.FromRgb((byte)(r * delta), (byte)(g * delta), (byte)(b * delta))
                    ;
                    colorList.Add(cwi);
                

        colorList.Sort();

        return colorList;
    




我的问题:

我想在 TextBox1 中查看选定的颜色十六进制字符串。

所以,假设我单击ComboBox,然后单击ComboBox 下拉菜单中的蓝色。如何在TextBox1 中看到#0000FF

【问题讨论】:

通过(ColorWithInfo)((ComboBox)sender).SelectedItem(ColorWithInfo)e.AddedItems[0]获取选中项。 ...然后放弃 WPF 中的 WinForms 样式。 @AdrianoRepetti 我从这里得到了这些代码。 wpf.2000things.com/2013/12/02/… @MarkMarkowitz 上线并不会自动生成 good WPF 代码! :) 说真的:在 WPF 中,您(应该)很少/几乎不需要直接处理事件,因为您正在使用 VM 和数据绑定。在这种情况下,选定的值是双向绑定到 VM 中的属性的,该属性(一种或两种方式)绑定到您的文本框的值(最终使用 ValueConverter 来匹配您想要的表示形式)。此外,ColorWithInfo 的东西很奇怪(而且 80%​​ 没用)。在这里,您将视图与 VM 混合在一起......令人困惑和冗长(IMO) 【参考方案1】:

回答 cmets 提出的其他问题... 要将 Hex 字符串添加到 ComboBox 中的每个项目,只需更改 DataTemplate 以包含一个 TextBlock 并将其绑定到 Color...

<ComboBox.ItemTemplate>
    <DataTemplate>
        <StackPanel>
            <Rectangle Height="55" Width="55" x:Name="Rectangle1">
                <Rectangle.Fill>
                    <SolidColorBrush Color="Binding Color"/>
                </Rectangle.Fill>
            </Rectangle>
            <TextBlock Text="Binding Color"/>
        </StackPanel>
    </DataTemplate>
</ComboBox.ItemTemplate>

注意:我还将您的 Grid 更改为水平 StackPanel 太简单了,以使其快速适应。您当然仍然可以使用 Grid 或至少让 StackPanel 看起来更好,但我会把它留给您。

【讨论】:

【参考方案2】:

试试这个:

private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)

    if (e.AddedItems.Count > 0)
    
        var selectedItem = (ColorWithInfo)e.AddedItems[0];
        TextBox1.Text = selectedItem.Color.ToString();
    

【讨论】:

完美。解决了。谢谢你。让我们更进一步。如何在打开的 DropDown 中查看每个 ComboBox 项上的每个十六进制字符串?因为我想看到每一种颜色和每一个十六进制串在一起。 您可以简单地更改 ComboBox 的 DataTemplate 以显示颜色矩形和十六进制字符串。

以上是关于由 Hue 组织的颜色选择框的主要内容,如果未能解决你的问题,请参考以下文章

文本框选择颜色和选择括号颜色

选择框边框颜色

怎么弄EXCEL表的下拉框,选择里面的项会自带颜色

颜色组合框和自定义颜色选择器

选择框背景颜色html

Winforms - 列表框项目悬停并选择颜色