WPF学习手记-04 Basic Brushse(二)

来源:互联网 发布:腾讯视频客户端mac版 编辑:程序博客网 时间:2024/05/17 10:43

SolidColorBrush想对应的是GradientBrush,表现为一种或多种颜色逐渐(线性)的变化,其实GradientBrush算是一个高级的主题了,但在WPF里面却可以非常容易的实现,先贴一段代码.

//-------------------------------------------------

// GradiateTheBrush.cs (c) 2006 by Charles Petzold

//-------------------------------------------------

using System;

using System.Windows;

using System.Windows.Input;

using System.Windows.Media;

 

namespace Petzold.GradiateTheBrush

{

    
public class GradiateTheBrush : Window

    
{

 

        [STAThread]

        
public static void Main()

        
{

            Application app 
= new Application();

            app.Run(
new GradiateTheBrush());

        }


        
public GradiateTheBrush()

        
{

            Title 
= "Gradiate the Brush";

 

            LinearGradientBrush brush 
=

                
new LinearGradientBrush(Colors.Red

, Colors.Blue,

                                        
new Point

(
00), new Point(11));

            Background 
= brush;

        }


    }


}


 

    

     我试着解释一下LinearGradientBrush,其最简单的形式是有两个点Point1和Point2对应2种颜色Color1和Color2,连接Point1和Point2的直线上的每一个点都是这两种颜色的混合颜色,中点恰好是”平均颜色”,而与这条直线垂直的线都拥有一致的颜色,这个颜色是按两种颜色经不同的不利混合而成的.

 

问题来了, LinearGradientBrush需要知道2个点,但是如果这2个点是动态的不是处理起来很麻烦,庆幸的是WPF已经作了这样的处理,比如将Window的背景设置为LinearGradientBrush,那么系统会假设左上角的坐标为(0,0),右下角的坐标为(1,1),这样当Window的大小发生变化时,Brush也会自动调整(这种自动调整也是Changed事件的作用),如果你不喜欢这种方式也可以, LinearGradientBrushMappingMode属性改为Absolute(默认为RelativeToBoundingBox)这样使用的就是前文提到的设备无关的单位,你可以这样修改上面的代码再看看效果.

LinearGradientBrush brush = new LinearGradientBrush(Colors.Red

, Colors.Blue, new Point(0, 0), new Point(100, 100));

brush.MappingMode = BrushMappingMode.Absolute;

LinearGradientBrush的构造函数里还可以定义角度angle,这个角度是针对(0,0)(1,1)说的,所以通常情况下Window或其它应用Brush的对象都不是正方形,所以你所看到的颜色的变化不是你所指定的angle是正常的,看下面一段代码

using System;

using System.Windows;

using System.Windows.Input;

using System.Windows.Media;

 

namespace Petzold.GradiateTheBrush

{

    
public class GradiateTheBrush : Window

    
{

        [STAThread]

        
public static void Main()

        
{

            Application app 
= new Application();

            app.Run(
new GradiateTheBrush());

        }


        
public GradiateTheBrush()

        
{

            Title 
= "Gradiate the Brush";

 

            LinearGradientBrush brush 
=

                
new LinearGradientBrush(Colors.Red

, Colors.Blue,

                                        
new Point

(
00), new Point(0.250.25));

 

            brush.SpreadMethod 
= GradientSpreadMethod.Reflect;

 

            Background 
= brush;

        }


    }


}


   

注意LinearGradientBrush的构造函数和SpreadMethod,你可以看到的效果是Red-Blue-Red-Blue-Red的颜色变化,很平缓的过度,因为采用了反射(Reflect)的方式扩展Brush,默认的方式是Pad,这种方式是用单色平铺区域,还有一种是Repeat,是重复显示

使用GradientStop可以为LinearGradientBrush定义多种颜色的效果

//-------------------------------------------------

// FollowTheRainbow.cs (c) 2006 by Charles Petzold

//-------------------------------------------------

using System;

using System.Windows;

using System.Windows.Input;

using System.Windows.Media;

 

namespace Petzold.FollowTheRainbow

{

    
class FollowTheRainbow : Window

    
{

 

        [STAThread]

        
public static void Main()

        
{

            Application app 
= new Application();

            app.Run(
new FollowTheRainbow());

        }


        
public FollowTheRainbow()

        
{

            Title 
= "Follow the Rainbow";

 

            LinearGradientBrush brush 
= new

 LinearGradientBrush();

            brush.StartPoint 
= new Point(00);

            brush.EndPoint 
= new Point(10);

            Background 
= brush;

 

            
// Rainbow mnemonic is the name Roy G.Biv.

                       brush.GradientStops.Add(
new

            GradientStop(Colors.Red, 
0));

            brush.GradientStops.Add(
new

 GradientStop(Colors.Orange, .
17));

            brush.GradientStops.Add(
new

 GradientStop(Colors.Yellow, .
33));

            brush.GradientStops.Add(
new

 GradientStop(Colors.Green, .
5));

            brush.GradientStops.Add(
new

 GradientStop(Colors.Blue, .
67));

            brush.GradientStops.Add(
new

 GradientStop(Colors.Indigo, .
84));

            brush.GradientStops.Add(
new

 GradientStop(Colors.Violet, 
1));

        }


    }


}

 

    下面来说说另外一种GradientBrush——RadialGradientBrush,现在把上面的程序略做调整.

//-------------------------------------------------

// CircleTheRainbow.cs (c) 2006 by Charles Petzold

//-------------------------------------------------

using System;

using System.Windows;

using System.Windows.Input;

using System.Windows.Media;

 

namespace Petzold.CircleTheRainbow

{

    
public class CircleTheRainbow : Window

    
{

 

        [STAThread]

        
public static void Main()

        
{

            Application app 
= new Application();

            app.Run(
new CircleTheRainbow());

        }


        
public CircleTheRainbow()

        
{

            Title 
= "Circle the Rainbow";

 

            RadialGradientBrush brush 
= new

 RadialGradientBrush();

            Background 
= brush;

 

            
// Rainbow mnemonic is the name Roy G.Biv.

            brush.GradientStops.Add(
new

 GradientStop(Colors.Red, 
0));

            brush.GradientStops.Add(
new

 GradientStop(Colors.Orange, .
17));

            brush.GradientStops.Add(
new

 GradientStop(Colors.Yellow, .
33));

            brush.GradientStops.Add(
new

 GradientStop(Colors.Green, .
5));

            brush.GradientStops.Add(
new

 GradientStop(Colors.Blue, .
67));

            brush.GradientStops.Add(
new

 GradientStop(Colors.Indigo, .
84));

            brush.GradientStops.Add(
new

 GradientStop(Colors.Violet, 
1));

        }


    }


}


 

RadialGradientBrush表现的区域是一个椭圆,它的定义依赖几个值,Center定义了椭圆的中心(Default:0.5,0.5),RadiusXRadiusY用来定义水平和竖直方向的半径Radii(Default:0.5),GradientOrigin定义了变化的中心点(其实我也说不明白了,自己试验一下可能更有心得吧),贴段代码

//-------------------------------------------------------

// ClickTheGradientCenter.cs (c) 2006 by Charles Petzold

//-------------------------------------------------------

using System;

using System.Windows;

using System.Windows.Input;

using System.Windows.Media;

 

namespace Petzold.ClickTheGradientCenter

{

    
class ClickTheRadientCenter : Window

    
{

        RadialGradientBrush brush;

 

        [STAThread]

        
public static void Main()

        
{

            Application app 
= new Application();

            app.Run(
new ClickTheRadientCenter());

        }


        
public ClickTheRadientCenter()

        
{

            Title 
= "Click the Gradient Center";

            brush 
= new RadialGradientBrush(Colors

.White, Colors.Red);

            brush.RadiusX 
= brush.RadiusY = 0.10;

            brush.SpreadMethod 
=

 GradientSpreadMethod.Repeat;

            Background 
= brush;

        }


        
protected override void OnMouseDown

(MouseButtonEventArgs args)

        
{

            
double width = ActualWidth

                
- 2 * SystemParameters

.ResizeFrameVerticalBorderWidth;

            
double height = ActualHeight

                
- 2 * SystemParameters

.ResizeFrameHorizontalBorderHeight

                
- SystemParameters.CaptionHeight;

 

            Point ptMouse 
= args.GetPosition(this);

            ptMouse.X 
/= width;

            ptMouse.Y 
/= height;

 

            
if (args.ChangedButton == MouseButton

.Left)

            
{

                brush.Center 
= ptMouse;

                brush.GradientOrigin 
= ptMouse;

            }


            
else if (args.ChangedButton ==

 MouseButton.Right)

                brush.GradientOrigin 
= ptMouse;

        }


    }


}


 

    Brush真的可以变换出很多很炫的效果,其背后的数学公式我暂时不想深究了,大家有更好的讲Brush的资料可以多多分享.

 
原创粉丝点击