65.9K
CodeProject 正在变化。 阅读更多。
Home

WPF 颜色选择器,类似 Office 2007

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.89/5 (59投票s)

2010年1月17日

CPOL

3分钟阅读

viewsIcon

134284

downloadIcon

7487

一个易于使用的颜色选择器,具有高级调色板,适用于 WPF 应用程序,具有 Office 2007 颜色选择器的外观和感觉。

main.JPG >

引言

最近,我正在开发一个 WPF 应用程序,该应用程序需要一个颜色选择器,用于设置应用程序中各种图形元素的颜色。起初,这对我来说似乎是一个五分钟的任务,因为我确信我可以在互联网上免费获得一个。我说的没错,直到有人告诉我它应该具有与 Office 2007 颜色选择器相似的外观和感觉。因此,我构建了自己的,这就是它。

特点

颜色选择器具有以下功能

  • 从预定义的颜色列表中选择颜色
  • 从颜色调色板中选择自定义颜色
  • 在自定义颜色选择模式下,使用滑块调整所选颜色的不透明度
  • 在 WPF 应用程序中的任何位置轻松使用,并为所选颜色提供单个可绑定属性。

实现

提供的源代码非常易于理解。所以我将重点介绍感兴趣的要点。让我们从如何在我们的应用程序中使用它开始。

基本上,该控件有三个文件,所以我已将其打包在 DLL 中。

<CustomWPFColorPicker:ColorPickerControlView x:Name="ForeColorPicker" />

该控件具有依赖属性“CurrentColor”,当从选择器中选择颜色时(无论是从预定义的颜色列表还是高级颜色调色板中选择),该属性都会更新。

public static DependencyProperty CurrentColorProperty = 
DependencyProperty.Register("CurrentColor", typeof(SolidColorBrush),
typeof(ColorPickerControlView), new PropertyMetadata(Brushes.Black)); 

选择器是一个经过少量样式编辑的 ToggleButton,用于在 <border> 内显示 CurrentColor。一个 Popup 包含预定义的颜色,就像 Office 2007 中一样。这些是一组 button,每个按钮都通过命令参数表示一种颜色。

<Button Click="Button_Click"  Style="{StaticResource ColorButtonStyleFirstRow}"
Command="{x:Static CustomWPFColorPicker:ColorPickerControlView.SelectColorCommand}" 
CommandParameter="#FFFFFF" Margin="3,4,3,4" Background="#FFFFFF" />

1.JPG

“更多颜色”按钮用于打开一个包含高级选择器的模型对话框,用户可以在其中用鼠标从颜色调色板中选择颜色。

2.JPG

颜色调色板是一张 JPG 图像,在鼠标按下事件期间读取 4 位,其中包含 ARGB 的颜色。

private void Image_MouseDown(object sender, MouseButtonEventArgs e)
        {
            try
            {
                var cb = new CroppedBitmap((BitmapSource)
		(((Image)e.Source).Source), new Int32Rect
		((int)Mouse.GetPosition(e.Source as Image).X, 
		(int)Mouse.GetPosition(e.Source as Image).Y, 1, 1));
                _pixels = new byte[4];
                try
                {
                    cb.CopyPixels(_pixels, 4, 0);
                    UpdateCurrentColor();
                    UpdateMarkerPosition();
                }
                catch
                {
                }
                UpdateSlider();
            }
            catch (Exception)
            {
            }
        }

使用这些位,颜色会更新

private void UpdateCurrentColor()
        {
            CurrentColor = Color.FromRgb(_pixels[2], _pixels[1], _pixels[0]);
            currentColorBorder.Background = 
	     new SolidColorBrush(Color.FromRgb(_pixels[2], _pixels[1], _pixels[0]));
            brightnessSlider.Value = 0.5;
            SelectedCurrentColor = new SolidColorBrush(CurrentColor);
        }

3.JPG

使用滑块来调整颜色值,以便用户可以获得更多所选颜色从白色到黑色的色调。我已经编辑了默认 WPF 滑块控件的样式,以获得您在演示中看到的外观。其背景反映了用户更改值时将获得的颜色阴影。为了实现这一点,我使用了 LinearGradientBrush,它在 0、0.5 和 1 点处有 3 个 GradientStop。在零处,颜色是白色,在 0.5 处,颜色是所选颜色,在 1 处,颜色是黑色。

<LinearGradientBrush x:Key="BrightnessGradient" StartPoint="0,1" EndPoint="0,0" 
        ColorInterpolationMode="ScRgbLinearInterpolation">
            <GradientStop Offset="0" Color="sc# 1, 0,0,0" />
            <GradientStop Offset="0.5" Color="sc# 1, 0.5,0.5,0.5" />
            <GradientStop Offset="1" Color="sc# 1, 1,1,1" />
        </LinearGradientBrush>

当滑块值发生变化时,我根据滑块的值计算颜色值。这里有两个特殊情况需要考虑。当滑块值接近 0 时,颜色应更接近白色。当滑块值接近 1 时,它应该接近黑色。在 0 时,颜色变为白色,在 1 时,颜色变为黑色。为此,我设计了一种非常简单易懂的高效算法。请注意,在这里我并没有简单地更改颜色的 alpha 值,而是在计算从白色到黑色的颜色阴影,包括所选颜色和其阴影正在调整的颜色。

void BrightnessSliderValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (_pixels == null)
            {
                _pixels = new byte[3];
                _pixels[2] = CurrentColor.R;
                _pixels[1] = CurrentColor.G;
                _pixels[0] = CurrentColor.B;
            }

            var nc = Color.FromRgb(_pixels[2], _pixels[1], _pixels[0]);
            var f = (float)e.NewValue;
            float r, g, b;
            const float a = 1;

            if (f >= 0.5f)
            {
                r = nc.ScR + (1 - nc.ScR) * (f - 0.5f) * 2;
                g = nc.ScG + (1 - nc.ScG) * (f - 0.5f) * 2;
                b = nc.ScB + (1 - nc.ScB) * (f - 0.5f) * 2;
            }
            else
            {
                r = nc.ScR * f * 2;
                g = nc.ScG * f * 2;
                b = nc.ScB * f * 2;
            }

            CurrentColor = Color.FromScRgb(a, r, g, b);
            currentColorBorder.Background = new SolidColorBrush(CurrentColor);
        }

结论

该控件最令人印象深刻的部分是滑块,它计算所选颜色的阴影。我希望该控件对那些需要 Office 2007 样式颜色选择器的用户有所帮助。如果您觉得这篇文章有趣,请为它投票。

历史

  • 2010 年 1 月 17 日:初始帖子
© . All rights reserved.