• 【WPF】打造Blend风格的BrushPicker(1)


    在贴出来上一篇文章后,感觉那个ColorPicker太简单了,于是决定搞个Blend中的那种ColorPicker。由于工作量比较大,所以打算分成几次来完成。

      

    首先说明一下,这个Demo还是属于未完成的阶段,比如ColorPicker的属性只是简单地设置了一个SelectedColor属性,而实际上分为A,R,G,B四个属性比较合适,这样可以在右边直接修改值;又比如,样式实在是很难看……(太累了,明天再说吧……)不过整体来看,还是能说明问题了。

    【分析】

        Blend中的ColorPicker其实应该分为好几个部分。首先是中间那个彩条状选择基色的Bar。我称之为ColorRainbowBar。然后是左侧基于给定的基色精确调节颜色的Box。我称之为ColorAdjuster。

        这两个控件都是基于偏移量(Offset)来确定颜色的,因此,我首先定义了一个基类ColorBoxBase来提供偏移量,以及通过鼠标点击和拖拽改变偏移量的逻辑。

    【控件的实现】

    ColorBoxBase

        这个是颜色选择器的基础。他提供了偏移量属性和鼠标事件改变偏移量的逻辑。

    Code

        代码有点长,但是大部分都是在定义依赖属性。注意,其中的HorizontalOffset和VerticalOffset都是只读属性。并且,实际上的“拖拽”逻辑并不直接去控制UI,而仅仅是改变了Offset,这种思路是WPF里面很常见的。稍后我们就会看到如何在模板里面通过绑定来实现拖拽的效果。

    ColorRainbowBar

        ColorRainbowBar由ColorBoxBase继承而来,比较有意思的是它的背景色,其实是一个有7个GradientStop的LinearGradientBrush

    Code

        其中,最主要的地方是根据Offset来确定颜色的代码。主要的原理在注释中写的比较清楚了。

    Code

        首先我们要根据偏移量算出属于哪个区间,然后算出相对于该区间的偏移量,接着根据最前面注释中的表中的分析,确定每个颜色的改变方向(FF还是00)。最后计算颜色。

        它的模板如下: 

    Code

        注意,里面放了个Thumb,但我却没有写任何拖拽的逻辑,只是简单的绑定到Offset而已。这样当我们用鼠标拖拽的时候,感觉上就是在拖拽这个Thumb了。

    ColorAdjuster

        ColorAdjuster比较麻烦,一个是它的颜色,并不是简单的LinearGradientBrush,而是包含了两个方向(水平和垂直)的复杂渐变。为了解决这个问题,我放置了两个Rectangle,一个在水平方向渐变填充,一个在垂直方向渐变填充。然后两者的颜色合成为最终的效果。需要特别注意的是,必须把LinearGradientBrush的ColorInterpolationMode设置为ScRgbLinearInterpolation,否则你会发现颜色叠加之后,中间有一条混合带的颜色特别明显。 

    另外,我将它的背景色固定为White,这个也算是讨巧了。因为两个方向的渐变均是渐变到透明,如果背景色不是白色的话,会跟控件下面的颜色发生混淆,影像颜色的效果。

    Code

    让我费了费脑子的是颜色的算法。为此,我专门画了一个图来分析。

        颜色的变化其实是一个F(x,y)的形式,跟水平和垂直的偏移量都有关系。同时计算其实比较难想,于是我把计算过程拆成步:首先计算水平偏移后的结果,接着水平偏移结果的基础上,接着计算垂直偏移。

    Code

    ColorPicker

        最后的工作就是把前面做的控件组合起来,做一个ColorPicker。我这里使用的是CustomControl,但其实UserControl也没什么问题。

    我原来的打算是做一个SolidColorBrushPicker,一个GradientBrushPicker,可以直接返回Brush,但今天实在太累了,也就凑合着做了个ColorPicker,主要是为了测试一下。明天开始继续进军BrushPicker。

    它没什么代码,就是一个模板。

    Code

    【下篇预告】

        好了,其实到此为止,我们需要攻坚的两个东东,ColorRainbowBar和ColorAdjuster已经完成了,剩下的任务就是把选出的Color转换成需要的Brush,下一篇里我打算讲讲怎么搞个SolidColorBrushPicker出来,如果快的话,估计GradientBrushPicker也能出来:)

    注:我的开发环境是Vista SP1 + .Net 3.5 SP1 + VS2008 SP1

    代码下载https://files.cnblogs.com/RMay/ColorPickerSeries/RMay.Demos.rar

  • 相关阅读:
    node.js
    js中文乱码问题
    238. Product of Array Except Self
    接下来要记得东西
    javascript 块内函数
    171. Excel Sheet Column Number
    Moore’s Voting Algorithm
    [ Python ] PIL
    [ Python ] KMP Algorithms
    房之事
  • 原文地址:https://www.cnblogs.com/RMay/p/1286879.html
Copyright © 2020-2023  润新知