转载 https://www.cnblogs.com/seekdream/p/5239149.html
什么是WPF中的画刷,顾名思义屏幕上可见的所有内容都可见,因为它是由画笔绘制的。 例如,画笔用于描述按钮的背景、文本的前景和形状的填充效果首先我们来看看WPF中包含哪些类型的画刷,下面的一组图片中描述了我们常用的画刷类型,后面我们通过一组具体的示例来讲述每一种画刷的具体使用方法。
图一 常见的画刷类型
1 SolidColorBrush
SolidColorBrush使用纯色绘制区域 Color 。 可以通过多种方式指定的 Color SolidColorBrush :例如,可以指定其 alpha、红色、蓝色和绿色通道,或使用类提供的预定义颜色之一 Colors 。
下面的示例使用 SolidColorBrush 绘制 Fill 的 Rectangle 。 下图显示了绘制的矩形
1.1 通过C#代码直接进行创建 Rectangle exampleRectangle = new Rectangle(); exampleRectangle.Width = 75; exampleRectangle.Height = 75; // Create a SolidColorBrush and use it to // paint the rectangle. SolidColorBrush myBrush = new SolidColorBrush(Colors.Red); exampleRectangle.Fill = myBrush; 1.2 在xaml中直接进行创建 <Rectangle Width="75" Height="75"> <Rectangle.Fill> <SolidColorBrush Color="Red" /> </Rectangle.Fill> </Rectangle>
2 GradientBrush
渐变画刷主要包括线性渐变绘制和径向渐变画刷绘制,下面分别来介绍着两种类型。
LinearGradientBrush使用线性渐变绘制区域。 线性渐变在线条(渐变轴)中混合了两种或多种颜色。 使用 GradientStop 对象可以指定渐变中的颜色及其位置。
下面的示例使用 LinearGradientBrush 绘制 Fill 的 Rectangle 。 下图显示了绘制的矩形。
2.1 使用C#代码进行创建 Rectangle exampleRectangle = new Rectangle(); exampleRectangle.Width = 75; exampleRectangle.Height = 75; // Create a LinearGradientBrush and use it to // paint the rectangle. LinearGradientBrush myBrush = new LinearGradientBrush(); myBrush.GradientStops.Add(new GradientStop(Colors.Yellow, 0.0)); myBrush.GradientStops.Add(new GradientStop(Colors.Orange, 0.5)); myBrush.GradientStops.Add(new GradientStop(Colors.Red, 1.0)); exampleRectangle.Fill = myBrush; 2.2 使用xaml进行创建 <Rectangle Width="75" Height="75"> <Rectangle.Fill> <LinearGradientBrush> <GradientStop Color="Yellow" Offset="0.0" /> <GradientStop Color="Orange" Offset="0.5" /> <GradientStop Color="Red" Offset="1.0" /> </LinearGradientBrush> </Rectangle.Fill> </Rectangle>
径向渐变画刷和这个类似,这里就不在进行单独讲述。
3 ImageBrush
这个是我们经常使用到的一种类型,比如我们经常会将一副图片来填充一个Rectangle的内部
图三 ImageBrush
3.1 使用C#代码创建 Rectangle exampleRectangle = new Rectangle(); exampleRectangle.Width = 75; exampleRectangle.Height = 75; // Create an ImageBrush and use it to // paint the rectangle. ImageBrush myBrush = new ImageBrush(); myBrush.ImageSource = new BitmapImage(new Uri(@"sampleImages\pinkcherries.jpg", UriKind.Relative)); exampleRectangle.Fill = myBrush; 3.2 使用xaml代码进行创建 <Rectangle Width="75" Height="75"> <Rectangle.Fill> <ImageBrush ImageSource="sampleImages\pinkcherries.jpg" /> </Rectangle.Fill> </Rectangle>
4 DrawingBrush
DrawingBrush使用绘制区域 Drawing 。 Drawing可以包含形状、图像、文本和媒体。
下面的示例使用 DrawingBrush 绘制 Fill 的 Rectangle 。 下图显示了绘制的矩形,我们来看一个具体的例子。
4.1 使用C#代码实现 Rectangle exampleRectangle = new Rectangle(); exampleRectangle.Width = 75; exampleRectangle.Height = 75; // Create a DrawingBrush and use it to // paint the rectangle. DrawingBrush myBrush = new DrawingBrush(); GeometryDrawing backgroundSquare = new GeometryDrawing( Brushes.White, null, new RectangleGeometry(new Rect(0, 0, 100, 100))); GeometryGroup aGeometryGroup = new GeometryGroup(); aGeometryGroup.Children.Add(new RectangleGeometry(new Rect(0, 0, 50, 50))); aGeometryGroup.Children.Add(new RectangleGeometry(new Rect(50, 50, 50, 50))); LinearGradientBrush checkerBrush = new LinearGradientBrush(); checkerBrush.GradientStops.Add(new GradientStop(Colors.Black, 0.0)); checkerBrush.GradientStops.Add(new GradientStop(Colors.Gray, 1.0)); GeometryDrawing checkers = new GeometryDrawing(checkerBrush, null, aGeometryGroup); DrawingGroup checkersDrawingGroup = new DrawingGroup(); checkersDrawingGroup.Children.Add(backgroundSquare); checkersDrawingGroup.Children.Add(checkers); myBrush.Drawing = checkersDrawingGroup; myBrush.Viewport = new Rect(0, 0, 0.25, 0.25); myBrush.TileMode = TileMode.Tile; exampleRectangle.Fill = myBrush; 4.2 使用xaml进行创建 这种方式是我们比较常用的一种方式,我们来具体看看 <Rectangle Width="75" Height="75"> <Rectangle.Fill> <DrawingBrush Viewport="0,0,0.25,0.25" TileMode="Tile"> <DrawingBrush.Drawing> <DrawingGroup> <GeometryDrawing Brush="White"> <GeometryDrawing.Geometry> <RectangleGeometry Rect="0,0,100,100" /> </GeometryDrawing.Geometry> </GeometryDrawing> <GeometryDrawing> <GeometryDrawing.Geometry> <GeometryGroup> <RectangleGeometry Rect="0,0,50,50" /> <RectangleGeometry Rect="50,50,50,50" /> </GeometryGroup> </GeometryDrawing.Geometry> <GeometryDrawing.Brush> <LinearGradientBrush> <GradientStop Offset="0.0" Color="Black" /> <GradientStop Offset="1.0" Color="Gray" /> </LinearGradientBrush> </GeometryDrawing.Brush> </GeometryDrawing> </DrawingGroup> </DrawingBrush.Drawing> </DrawingBrush> </Rectangle.Fill> </Rectangle>
5 VisualBrush
这个是我们可能使用不太多并且不是非常数量的例子,我们这里对这个进行重点的解释一下,首先看看VisualBrush的解释,msdn上面的解释是使用 Visual 绘制区域,那么我们再来看看什么是Visual呢?官方的解释是:获取或设置画笔的内容,Visual 是直接继承自DependencyObject,UIElement也是直接继承自Visual,我们常见的控件都是继承自Visual,Visual可以实现动态绑定,比如我们可以在代码中这样写:
1
这样我们就可以把一个继承自Visual的控件(此处为TodayPeriod的一个UserControl)通过绑定的方式绑定到Visual中,我们再来看看VisualBrush这个类,首先来看一段示例代码:
System.Object
System.Windows.Threading.DispatcherObject System.Windows.DependencyObject System.Windows.Freezable System.Windows.Media.Animation.Animatable System.Windows.Media.Brush System.Windows.Media.TileBrush System.Windows.Media.VisualBrush
所以在上面的代码中我们可以设置Border的Background为VisualBrush,我们在很多地方都是可以使用VisualBrush的,这里需要我们平时在使用的时候不断去反思去总结。
扩展应用
另外一个常用到VisualBrush的地方就是使用DrawingContext的时候,因为DrawingContext的第一个参数就是Brush,这里我们经常可以使用VisualBrush作为对象传递进去,比如下面的例子我们需要将WPF中的MainWindow保存为一张图片保存到本地,这个时候VisualBrush就派上用场了,我们来看下面的例子。
public static void CreateBitmapFromVisual(Visual target, string fileName) {
if (target == null || string.IsNullOrEmpty(fileName)) {
return; } Rect bounds = VisualTreeHelper.GetDescendantBounds(target); RenderTargetBitmap renderTarget = new RenderTargetBitmap((Int32)bounds.Width, (Int32)bounds.Height, 96, 96, PixelFormats.Pbgra32); DrawingVisual visual = new DrawingVisual(); using (DrawingContext context = visual.RenderOpen()) {
VisualBrush visualBrush = new VisualBrush(target); context.DrawRectangle(visualBrush, null, new Rect(new Point(), bounds.Size)); } renderTarget.Render(visual); PngBitmapEncoder bitmapEncoder = new PngBitmapEncoder(); bitmapEncoder.Frames.Add(BitmapFrame.Create(renderTarget)); using (Stream stm = File.Create(fileName)) {
bitmapEncoder.Save(stm); } }
这里传入的参数是target和fileName,前者是一个Visual,通过继承关系我们知道大部分的控件都是从Visual继承下来的,在这个方法中我们首先创建DrawingVisual对象,然后用这个对象创建drawingContext,然后使用drawingContext的DrawRectangle方法来绘制对象,这里传入的第一个参数就是包含传入target对象的VisualBrush对象,通过这个过程我们就能准确地将试图对象保存成一个完整的图片了。
我们再以前面的Rectangle为示例来进行说明从而加深对整个知识点的掌握程度,我们首先来看下面的截图。
图五 VisualBrush
5.1 C#代码的实现 Rectangle exampleRectangle = new Rectangle(); exampleRectangle.Width = 75; exampleRectangle.Height = 75; // Create a VisualBrush and use it // to paint the rectangle. VisualBrush myBrush = new VisualBrush(); // // Create the brush's contents. // StackPanel aPanel = new StackPanel(); // Create a DrawingBrush and use it to // paint the panel. DrawingBrush myDrawingBrushBrush = new DrawingBrush(); GeometryGroup aGeometryGroup = new GeometryGroup(); aGeometryGroup.Children.Add(new RectangleGeometry(new Rect(0, 0, 50, 50))); aGeometryGroup.Children.Add(new RectangleGeometry(new Rect(50, 50, 50, 50))); RadialGradientBrush checkerBrush = new RadialGradientBrush(); checkerBrush.GradientStops.Add(new GradientStop(Colors.MediumBlue, 0.0)); checkerBrush.GradientStops.Add(new GradientStop(Colors.White, 1.0)); GeometryDrawing checkers = new GeometryDrawing(checkerBrush, null, aGeometryGroup); myDrawingBrushBrush.Drawing = checkers; aPanel.Background = myDrawingBrushBrush; // Create some text. TextBlock someText = new TextBlock(); someText.Text = "Hello, World"; FontSizeConverter fSizeConverter = new FontSizeConverter(); someText.FontSize = (double)fSizeConverter.ConvertFromString("10pt"); someText.Margin = new Thickness(10); aPanel.Children.Add(someText); myBrush.Visual = aPanel; exampleRectangle.Fill = myBrush; 5.2 使用xaml实现 <Rectangle Width="75" Height="75"> <Rectangle.Fill> <VisualBrush TileMode="Tile"> <VisualBrush.Visual> <StackPanel> <StackPanel.Background> <DrawingBrush> <DrawingBrush.Drawing> <GeometryDrawing> <GeometryDrawing.Brush> <RadialGradientBrush> <GradientStop Color="MediumBlue" Offset="0.0" /> <GradientStop Color="White" Offset="1.0" /> </RadialGradientBrush> </GeometryDrawing.Brush> <GeometryDrawing.Geometry> <GeometryGroup> <RectangleGeometry Rect="0,0,50,50" /> <RectangleGeometry Rect="50,50,50,50" /> </GeometryGroup> </GeometryDrawing.Geometry> </GeometryDrawing> </DrawingBrush.Drawing> </DrawingBrush> </StackPanel.Background> <TextBlock FontSize="10pt" Margin="10">Hello, World!</TextBlock> </StackPanel> </VisualBrush.Visual> </VisualBrush> </Rectangle.Fill> </Rectangle>