Showing posts with label Brushes. Show all posts
Showing posts with label Brushes. Show all posts

Monday, March 7, 2011

Visual Brush in WPF (XAML)

Introduction

In this article describes how to use a VisualBrush in WPF. VisualBrush is a new addition to the brush types since GDI+. A VisualBrush is used to fill UI elements.

With a VisualBrush, you can define a simple or complex UI element and assign it to the VisualBrush.Visual property. Then you can paint other parts of your screen with this conglomerate brush. You get a number of performance benefits from the VisualBrush because WPF can use a copy of the the pixels it has already rendered.
VisualBrush has five TileMode properties:

  1. FlipX
  2. FlipY
  3. FlipXY
  4. None
  5. Tile

Getting Started

The VisualBrush element of XAML represents a Visual Brush. You treat this brush as other brushes. For example, you can set this brush as a background property of a window or a control. The TileMode property is used to set the tile of the brush. The Visual property of VisualBrush sets the visual and it can be an image. For example, the following code snippet creates a VisualBrush and sets its FlipX and Visual properties.

 

<VisualBrush TileMode="FlipX" Viewport="0,0,0.5,0.5">
<VisualBrush.Visual>
<Image Source="Raj 039.JPG"></Image>
</VisualBrush.Visual>
</VisualBrush>


The following code snippet sets the visual property to an Image.

FlipX:

<Window
x:Class="WPF_VisualBrush.Window1"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="VisualBrush in WPF" Height="400" Width="400">
<Window.Background>
<VisualBrush TileMode="FlipX" Viewport="0,0,0.5,0.5">
<VisualBrush.Visual>
<Image Source="Raj 039.JPG"></Image>
</VisualBrush.Visual>
</VisualBrush>
</Window.Background>
</Window>


The output looks like Figure 1.

Figure1


FlipY:


<Window x:Class="WPF_VisualBrush.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="VisualBrush in WPF" Height="400" Width="400">
<Window.Background>
<VisualBrush TileMode="FlipY" Viewport="0,0,0.5,0.5">
<VisualBrush.Visual>
<Image Source="Raj 039.JPG"></Image>
</VisualBrush.Visual>
</VisualBrush>
</Window.Background>
</Window>



The FlipY output looks like Figure 2.

Figure 2.

FlipXY:

<Window x:Class="WPF_VisualBrush.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="VisualBrush in WPF" Height="400" Width="400">
<Window.Background>
<VisualBrush TileMode="FlipXY" Viewport="0,0,0.5,0.5">
<VisualBrush.Visual>
<Image Source="Raj 039.JPG"></Image>
</VisualBrush.Visual>
</VisualBrush>
</Window.Background>
</Window>



The FlipXY output looks like Figure 3.


Figure 3.
None:

<Window x:Class="WPF_VisualBrush.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="VisualBrush in WPF" Height="400" Width="400">
<Window.Background>
<VisualBrush TileMode="None" Viewport="0,0,0.5,0.5">
<VisualBrush.Visual>
<Image Source="Raj 039.JPG"></Image>
</VisualBrush.Visual>
</VisualBrush>
</Window.Background>
</Window>



The None (no visual brush) output looks like Figure 4.

Figure 4.
Tile:

<Window x:Class="WPF_VisualBrush.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="VisualBrush in WPF" Height="400" Width="400"> <Window.Background>
<VisualBrush TileMode="Tile" Viewport="0,0,0.5,0.5">
<VisualBrush.Visual>
<Image Source="Raj 039.JPG"></Image>
</VisualBrush.Visual>
</VisualBrush>
</Window.Background>
</Window>



The Tile output looks like Figure 5.


Figure 5.

The Visual Brush can be applied to any control. It doesn't have to be a Windows as shown in my previous example. It can be a button, a rectangle, or a TextBox.

Let's see one more example with a Rectangle. In the following code snippet, I will a rectangle with a Visual Brush and set its TileMode property.

<Window x:Class="WPF_VisualBrush.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window2">
<DockPanel>
<StackPanel Margin="5" x:Name="Panel">
<Button>Button</Button>
<CheckBox>CheckBox</CheckBox>
<TextBox></TextBox>
</StackPanel>
<Rectangle>
<Rectangle.Fill>
<VisualBrush TileMode="FlipXY" Viewport="0,0,0.5,0.5" Visual="{Binding ElementName=Panel}"></VisualBrush>
</Rectangle.Fill>
</Rectangle>
</DockPanel>
</Window>



The output generates the following Figure.


Summary
In this article, we discussed how to use a VisualBrush in WPF.

Brushes in WPF (XAML)

 

Introduction

Brushes and pens are objects used to draw and fill graphics objects. In this article, I will discuss various types of brushes available in XAML and WPF model, their members, and properties and how to use them in your applications.

WPF and XAML work together and there is an WPF class corresponding to each XAML control. For example, <SolidColorBrush> tag in XAML and SolidColorBrush class in WPF, both represent the solid color brush. You can create and use brushes in both ways seperately or mix them. For example, I can create a brush using XAML and then later set the same brushes property dynamically in my coding using WPF class model.

In XAML and WPF model provides following brush objects  -

  1. SolidColorBrush
  2. LinearGradientBrush
  3. RadialGradientBrush
  4. DrawingBrush
  5. Visual Brush
  6. ImageBrush

1. Solid Color Brush

The <SolidColorBrush/> represents the solid color brush in XAML. The Color attribute of the tag represents the color used in the brush. For example, the following code creates a solid color brush with blue color.

<SolidColorBrush Color="Blue" />


The Color attribute can also be a hex value instead of the color name. The following code uses hex value of a color.

<SolidColorBrush Color="#FFFFFF" />


The following code fills a rectangle with black color.


<Rectangle Width="200" Height="40" Stroke="Blue" StrokeThickness="1">

<Rectangle.Fill>

<SolidColorBrush Color="#000000" />

</Rectangle.Fill>

</Rectangle>


The output looks like Figure 1, which is a filled rectangle with black color.


Figure 1. Rectangle with a solid brush

2. Linear Gradient Brush

The <LinearGradientBrush> object represents the linear gradient brush in XAML.


<Rectangle Width="200" Height="40" Stroke="Blue" StrokeThickness="3">

<Rectangle.Fill>

<LinearGradientBrush>

<GradientStop Offset="0" Color="Red"/>

<GradientStop Offset="1" Color="Green"/>

</LinearGradientBrush>

</Rectangle.Fill>

</Rectangle>


The output looks like Figure 2.


Figure 2. Rectangle filled with a linear gradient brush.

3. Radial Gradient Brush

The <RadialGradientBrush/> represents the radial gradient brush in XAML. Radial gradient brush provides gradient similar to linear gradient brush, however a linear gradient brush has a start point and end point and blending is done from the start and ending, while radial gradient brush has a circle.

In a radial gradient brush, you specify the gradient origin, center, and circle's X,Y radus values and GradientStop attribute specify the color of the graident.

The following source code draws a rectangle and fills with a radial gradient brush with multiple colors.


<Rectangle Width="300" Height="300" Stroke="Black" StrokeThickness="2">

<Rectangle.Fill>

<RadialGradientBrush GradientOrigin="0.1,0.4" Center="0.6,0.5" RadiusX="0.5" RadiusY="0.5">

<GradientStop Color="Red" Offset="0" />

<GradientStop Color="Black" Offset="0.20" />

<GradientStop Color="Yellow" Offset="0.40" />

<GradientStop Color="Pink" Offset="0.60" />

<GradientStop Color="Blue" Offset="0.80" />

<GradientStop Color="Green" Offset="1.0" />

</RadialGradientBrush>

</Rectangle.Fill>

</Rectangle>


The output looks like Figure 3.


Figure 3. Rectangle filled with a radial gradient brush

4. Drawing Brush

Drawing Brush is a new addition to the brush types since GDI+.  A Drawing Brush can be used to paint an area with shapes, text, images, and even video. The <DrawingBrush/> represents the drawing brush in XAML. A Drawing Brush uses drawing objects GeomertyDrawing, ImageDrawing, VideoDrawing, and GylphRunDrawing to draw shapes, images, video, and text respectively.

The following code uses a DrawingBrush to fill two ellipses. I will cover DrawingBrush objects, its methods and properties in more details in my seperate article.


<Rectangle Width="300" Height="300" Stroke="Black" StrokeThickness="2">

<Rectangle.Fill>

<DrawingBrush>

<DrawingBrush.Drawing>

<GeometryDrawing Brush="Green">

<GeometryDrawing.Geometry>

<GeometryGroup>

<EllipseGeometry RadiusX="0.1" RadiusY="0.5" Center="0.5,0.5" />

<EllipseGeometry RadiusX="0.5" RadiusY="0.1" Center="0.5,0.5" />

</GeometryGroup>

</GeometryDrawing.Geometry>

</GeometryDrawing>

</DrawingBrush.Drawing>

</DrawingBrush>

</Rectangle.Fill>

</Rectangle>


The output looks like Figure 4.


Figure 4. Rectangle filled with a drawing brush

5. Visual Brush

VisualBrush is a new addition to the brush types since GDI+.  A VisualBrush is used to fill UI elements. The following code uses a VisualBrush to fill a rectangle. I will cover VisualBrush object, its methods and properties in more details in my seperate article.


<Rectangle Width="200" Height="100">

<Rectangle.Fill>

<VisualBrush TileMode="Tile">

<VisualBrush.Visual>

<StackPanel>

<StackPanel.Background>

<DrawingBrush>

<DrawingBrush.Drawing>

<GeometryDrawing>

<GeometryDrawing.Brush>

<RadialGradientBrush>

<GradientStop Color="Green" 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="14pt" FontWeight="Bold" Margin="10">Visual Brush</TextBlock>

</StackPanel>

</VisualBrush.Visual>

</VisualBrush>

</Rectangle.Fill>

</Rectangle>


The output looks like Figure 5.



Figure 5. Rectangle filled with a visual brush

Learn more about Visual Brushes here: Visual Brush in WPF by Raj Kumar.

6. Image Brush

An image brush uses an image as fill color to fill graphics objects such as a recntagle, ellipse, and path. The <ImageBrush/> represents the image brush in XAML.  The BitmapSource property represents the image used to fill the brush.

For example, the following code fills a rectangle with an ImageBrush.


<Rectangle Width="100" Height="100" Stroke="Black" StrokeThickness="3">

<Rectangle.Fill>

<ImageBrush ImageSource="Milk.jpg"/>

</Rectangle.Fill>

</Rectangle>


The output looks like Figure 6.


Image 6. Rectangle with an image brush.

Summary

In this article, I discussed brushes available in XAML and WPF model. Clearly, there have been some improvements and additions in brushes in XAML and WPF model since GDI+.







Colors and Brushes in wpf

Colors class and Brushes class provides a collection of static read-only properties with all the named colors.

Notice the names are in plural. But Brushes provide return objects of type SolidColorBrush. Instead of setting the Background property like this:

Background = new SolidColorBrush(Colors.PaleGoldenrod);

you can use this:

Background = Brushes.PaleGoldenrod;

Although these two statements will certainly color your window background with the same color, there is a difference between the two approaches that reveals itself in a program like VaryTheBackground. In that program try replacing the following field definition:

SolidColorBrush brush = new SolidColorBrush(Colors.Black);


with

SolidColorBrush brush = Brushes.Black;


And when you do:

brush.Color = clr; 


In second case, you will get an Invalid Operation Exception that states "Cannot set a property on object '#FF000000' because it is in a read-only state." The problem is the very last statement in the OnMouseMove method, which attempts to set the Color property of the brush. (The hexadecimal number quoted in the exception is the current value of the Color property.)

Read more about Brushes : http://msdn.microsoft.com/en-us/library/system.windows.media.brushes.aspx

Predefined Brushes Are Already Frozen

The SolidColorBrush objects returned from the Brushes class are in a frozen state, which means they can no longer be altered. freezing is implemented in the Freezable class, from which Brush inherits. If the CanFreeze property of a Freezable object is true, it's possible to call the Freeze method to render the object frozen and unchangeable. The IsFrozen property indicates this state by becoming true.

Freezing objects can improve performance because they no longer need to be monitored for changes. A frozen Freezable object can also be shared across threads, while an unfrozen Freezable object cannot. Although you cannot unfreeze a frozen object, you can make an unfrozen copy of it.

The idea of an object deriving from Freezable is that it normally is in a read/write state, but can be explicitly put into a read-only state using the Freeze method.  A frozen object can be used more efficiently in WPF because it doesn’t need to notify consumers of the object that its value has changed.

Graphical objects in WPF like brushes and 3D geometries derive from Freezable.  Initially unfrozen, a change to one of these objects results in consumers of the objects being notified of the change.

If you have an object deriving from Freezable that you don’t plan to change, you can make the object read-only using the Freeze method.1    // Freeze this object, making it read-only (since we don't plan on changing it)

if (theBrush.CanFreeze)
theBrush.Freeze();

After freezing the object, if you try modifying it, you’ll get an InvalidOperationException.  But WPF will be more efficient in its use of the object.