【问题标题】:A Color Selection Box Organized by Hue由 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)

标签: c# wpf


【解决方案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 以显示颜色矩形和十六进制字符串。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-16
    • 2021-10-24
    • 2014-12-17
    • 1970-01-01
    • 1970-01-01
    • 2012-06-20
    • 2021-12-25
    相关资源
    最近更新 更多