WPF 颜色选择器,类似 Office 2007






4.89/5 (59投票s)
一个易于使用的颜色选择器,具有高级调色板,适用于 WPF 应用程序,具有 Office 2007 颜色选择器的外观和感觉。

引言
最近,我正在开发一个 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" />
“更多颜色”按钮用于打开一个包含高级选择器的模型对话框,用户可以在其中用鼠标从颜色调色板中选择颜色。

颜色调色板是一张 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);
}
使用滑块来调整颜色值,以便用户可以获得更多所选颜色从白色到黑色的色调。我已经编辑了默认 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 日:初始帖子