Shapes

  • 16 minutes to read

The WinForms Rich Text Editor allows you to view, print, and export documents that contain shapes to PDF. The Rich Text Editor supports all shape types from simple lines and rectangles to shapes with advanced effects.

Shapes in the Rich Text Editor

Shapes in the User Interface

The Rich Text Editor allows users to insert pictures and text boxes only. It does not contain user interface elements to create other shape types.

Rich Text Editor - Insert Tab

Users can move, resize, rotate, and delete existing shapes.

Rich Text Editor - Rotate Shapes

When a user selects a shape, the Picture Tools contextual tab appears. Tab items allow users to format the shape, define its position, and specify how text wraps around the shape.

Rich Text Editor - Picture Tools

Advanced shape properties are available in the Shape Layout Dialog. Right-click a shape and select More Layout Options... to invoke this dialog.

Shape Layout - Position tab

Manage Shapes in Code

Use the SubDocument.Shapes property to access a document's collection of drawing objects: shapes, pictures, and text boxes.

IMPORTANT

The Rich Text Editor does not support shapes in OpenDocument Text (.odt) documents.

Access Shapes

The ShapeCollection.Item property uses a shape's name or index to return the corresponding Shape object from the collection. Use the Shape.Type property to determine the shape type.

Document document = richEditControl.Document;
// Access the first shape in the collection.
Shape shape1 = document.Shapes[0];

// Access the shape with the specified name. 
Shape shape2 = document.Shapes["Rectangle 1"];
TIP

Use the ReadOnlyShapeCollection.Get method to retrieve all shapes from the specified document range.

Create Shapes

Use the ShapeCollection.InsertShape method overloads to add a shape to a document. A ShapeGeometryPreset enumeration member defines the shape's geometry.

The example below creates a rectangle.

Add a rectangle to a document

Document document = richEditControl.Document;
document.Unit = DevExpress.Office.DocumentUnit.Inch;
// Create a rectangle.
Shape rectangle = document.Shapes.InsertShape(document.Range.Start, ShapeGeometryPreset.Rectangle, new RectangleF(1.5f, 1f, 2f, 1.5f));
// Fill the rectangle with color.
rectangle.Fill.SetSolidFill(Color.FromArgb(0xFF, 0xEE, 0xAD));
// Format the rectangle border.
ShapeLine border = rectangle.Line;
border.Color = Color.FromArgb(0x4D, 0x64, 0x8D);
border.Thickness = 6;
border.JoinType = LineJoinType.Miter;

Insert Pictures

Call the ShapeCollection.InsertPicture method to insert a picture into a document. Use the Shape.PictureFormat property to access picture settings.

The example below inserts a picture with rounded corners.

Add a picture to a document

Document document = richEditControl.Document;
// Insert a picture.
Shape picture = document.Shapes.InsertPicture(document.Range.Start, DocumentImageSource.FromFile("Dog.png"));
// Change the picture's form.
picture.PictureFormat.Preset = ShapeGeometryPreset.RoundedRectangle;
// Display a border around the picture.
picture.Line.Color = Color.Black;
picture.Line.Thickness = 3;
// Align the picture.
picture.VerticalAlignment = ShapeVerticalAlignment.Top;
picture.HorizontalAlignment = ShapeHorizontalAlignment.Center;
NOTE

Pictures are stored in two collections: ShapeCollection and DocumentImageCollection.

Create Text Boxes

Call the ShapeCollection.InsertTextBox method to add a text box to a document. Use the Shape.ShapeFormat.TextBox.Document property to access and modify text box content.

The example below creates a text box.

Create a text box

Document document = richEditControl.Document;
document.Unit = DevExpress.Office.DocumentUnit.Inch;
// Create a text box.
Shape myTextBox = document.Shapes.InsertTextBox(document.Range.Start, new RectangleF(1.5f, 1f, 1.5f, 0.5f));
// Specify the text box background color.
myTextBox.Fill.Color = System.Drawing.Color.WhiteSmoke;
// Draw a border around the text box.
myTextBox.Line.Color = System.Drawing.Color.Black;
myTextBox.Line.Thickness = 1;
// Modify text box content.
SubDocument textBoxDocument = myTextBox.ShapeFormat.TextBox.Document;
textBoxDocument.AppendText("Text box");
CharacterProperties cp = textBoxDocument.BeginUpdateCharacters(textBoxDocument.Range.Start, 4);
cp.ForeColor = System.Drawing.Color.Orange;
cp.FontSize = 24;
textBoxDocument.EndUpdateCharacters(cp);

Use the following properties to determine whether a drawing object is a text box:

Insert Drawing Canvas

The ShapeCollection.InsertCanvas method inserts a drawing canvas into a document. Use the Shape.CanvasItems property to access the canvas item collection. The collection's Add methods allow you to add shapes and pictures to the canvas.

The example below adds a drawing canvas to the document.

Add a canvas to ShapeCollection

Document document = richEditControl.Document;
// Set the measurement unit to inches.
document.Unit = DevExpress.Office.DocumentUnit.Inch;
// Insert a drawing canvas.
Shape canvas = document.Shapes.InsertCanvas(document.Range.Start, new RectangleF(1.5f, 1f, 6f, 1.5f));
// Access the collection of canvas items. 
var canvasItems = canvas.CanvasItems;
// Add a rectangle to the canvas.
var shape1 = canvasItems.AddShape(ShapeGeometryPreset.Rectangle, new RectangleF(0f, 0f, 2f, 1.5f));
shape1.Fill.SetSolidFill(Color.FromArgb(0xA4, 0xFF, 0xFF));
shape1.Line.Color = Color.DarkGray;
shape1.Line.Thickness = 2;
// Add a picture to the canvas.
var shape2 = canvasItems.AddPicture(DocumentImageSource.FromFile("Picture_Arrow.png"), new PointF(2.1f, 0.3f));
// Add a parallelogram to the canvas.
var shape3 = canvasItems.AddShape(ShapeGeometryPreset.Parallelogram, new RectangleF(3.8f, 0f, 2f, 1.5f));
shape3.Fill.SetSolidFill(Color.FromArgb(0xFF, 0xA5, 0xA5));
shape3.Line.Color = Color.DarkGray;
shape3.Line.Thickness = 2;

Format Shapes

Use the following properties to customize shape appearance:

Property Description
Shape.Fill Provides access to shape fill options.
Shape.Line Provides access to format settings for a line or a shape's border.
ShapeLine.Fill Specifies line fill options.

The example below shows how to create a rectangle and change its border settings.

Rich_ShapeLine_Settings

// Add a rectangle to a document.
Shape rectangle = document.Shapes.InsertShape(document.Range.Start, ShapeGeometryPreset.Rectangle, new RectangleF(300, 200, 500, 300));
// Fill the rectangle with color.
rectangle.Fill.SetSolidFill(Color.FromArgb(0xFF, 0xEE, 0xAD));
// Format the rectangle border.
ShapeLine border = rectangle.Line;
border.Color = Color.FromArgb(0x4D, 0x64, 0x8D);
border.Thickness = 6;
border.JoinType = LineJoinType.Miter;
border.DashType = LineDashType.Solid;
border.CompoundType = LineCompoundType.ThickThin;

Position Shapes

A shape is anchored to a document range defined by the Shape.Range property. You can position the shape anywhere on the page that contains the anchor.

Horizontal and Vertical Alignment

Property Description
Shape.HorizontalAlignment Aligns a shape horizontally relative to the element specified by the Shape.RelativeHorizontalPosition property.
Shape.VerticalAlignment Aligns a shape vertically relative to the element specified by the Shape.RelativeVerticalPosition property.

The following example displays a rectangle in the center of the page below the top margin:

Document document = richEditControl.Document;
// Create a rectangle.
Shape rectangle = document.Shapes.InsertShape(document.Range.Start, ShapeGeometryPreset.Rectangle, new SizeF(500, 300));
// Align the rectangle horizontally and vertically.
rectangle.RelativeHorizontalPosition = ShapeRelativeHorizontalPosition.Page;
rectangle.HorizontalAlignment = ShapeHorizontalAlignment.Center;
rectangle.RelativeVerticalPosition = ShapeRelativeVerticalPosition.Margin;
rectangle.VerticalAlignment = ShapeVerticalAlignment.Top;

Absolute Position

Property Description
Shape.OffsetX Specifies a shape's horizontal position relative to the element defined by the Shape.RelativeHorizontalPosition property.
Shape.OffsetY Specifies a shape's vertical position relative to the element defined by the Shape.RelativeVerticalPosition property.
Shape.Offset Allows you to specify both the horizontal and vertical positions of a shape.
NOTE

The Offset properties are in effect when the Shape.HorizontalAlignment and Shape.VerticalAlignment properties are set to None.

The example below creates a rectangle and places it on the page as follows:

  • the absolute horizontal position is two inches to the right of the page;

  • the absolute vertical position is one inch below the page.

Document document = richEditControl.Document;
// Set the measurement unit to inches.
document.Unit = DevExpress.Office.DocumentUnit.Inch;
// Create a rectangle.
Shape rectangle = document.Shapes.InsertShape(document.Range.Start, ShapeGeometryPreset.Rectangle, new SizeF(2.5f, 1.5f));
// Specify the rectangle position on the page.
rectangle.RelativeHorizontalPosition = ShapeRelativeHorizontalPosition.Page;
rectangle.OffsetX = 2;
rectangle.RelativeVerticalPosition = ShapeRelativeVerticalPosition.Page;
rectangle.OffsetY = 1;

Relative Position

Property Description
Shape.OffsetXRelative Specifies a shape's horizontal position (as a percentage) relative to the element defined by the Shape.RelativeHorizontalPosition property.
Shape.OffsetYRelative Specifies a shape's vertical position (as a percentage) relative to the element defined by the Shape.RelativeVerticalPosition property.
Shape.OffsetRelative Allows you to specify a shape's relative horizontal and vertical positions.
NOTE

The OffsetRelative properties are in effect when the Shape.HorizontalAlignment and Shape.VerticalAlignment properties are set to None.

The example below creates a rectangle and places it on the page as follows:

  • the horizontal offset is equal to 20% of the page width,

  • the vertical offset is equal to 10% of the page height.

Document document = richEditControl.Document;
// Set the measurement unit to inches.
document.Unit = DevExpress.Office.DocumentUnit.Inch;
// Create a rectangle.
Shape rectangle = document.Shapes.InsertShape(document.Range.Start, ShapeGeometryPreset.Rectangle, new SizeF(2.5f, 1.5f));
// Specify the rectangle position on the page.
rectangle.RelativeHorizontalPosition = ShapeRelativeHorizontalPosition.Page;
rectangle.OffsetXRelative = 0.2f;
rectangle.RelativeVerticalPosition = ShapeRelativeVerticalPosition.Page;
rectangle.OffsetYRelative = 0.1f;

Text Wrapping

Use the following properties to specify how text wraps around a shape:

Property Description
Shape.TextWrapping Specifies the text wrapping style.
Shape.TextWrappingSide Allows you to specify which sides to wrap text around.
Shape.MarginTop
Shape.MarginBottom
Shape.MarginLeft
Shape.MarginRight
Define the distance between the shape and surrounding text.

The example below demonstrates how to wrap text around a shape.

Wrap text around a rectangle

Document document = richEditControl.Document;
document.LoadDocument("FirstLook.docx");
// Set the measurement unit to inches.
document.Unit = DevExpress.Office.DocumentUnit.Inch;

// Create a rectangle with a folded corner.
Shape rectangle = document.Shapes.InsertShape(document.CreatePosition(100), ShapeGeometryPreset.FoldedCorner);
// Center the rectangle on the page.
rectangle.RelativeHorizontalPosition = ShapeRelativeHorizontalPosition.Page;
rectangle.HorizontalAlignment = ShapeHorizontalAlignment.Center;
rectangle.RelativeVerticalPosition = ShapeRelativeVerticalPosition.Page;
rectangle.VerticalAlignment = ShapeVerticalAlignment.Center;

// Wrap text around the rectangle.
rectangle.TextWrapping = TextWrappingType.Square;

// Set the distance between the rectangle and text.
rectangle.MarginTop = 0.1f;
rectangle.MarginBottom = 0.1f;
rectangle.MarginLeft = 0.2f;
rectangle.MarginRight = 0.2f;

Inline Drawing Objects

Set the Shape.TextWrapping property to TextWrappingType.InLineWithText to convert a floating object to an inline shape.

The example below demonstrates how to insert an inline shape.

An inline shape

Document document = richEditControl.Document;
// Set the measurement unit to inches.
document.Unit = DevExpress.Office.DocumentUnit.Inch;

// Append text to the document.
document.AppendText("The plus sign is a binary operator that indicates addition.");

// Create a plus sign.
Shape rectangle = document.Shapes.InsertShape(document.CreatePosition(13), ShapeGeometryPreset.Plus);
// Set the shape size.
rectangle.Size = new SizeF(0.25f, 0.25f);

// Place the shape in line with text.
rectangle.TextWrapping = TextWrappingType.InLineWithText;

Resize Shapes

Absolute Size

Property Description
Shape.Height Specifies the shape's height in measurement units defined by the Document.Unit property.
Shape.Width Specifies the shape's width in measurement units defined by the Document.Unit property.
Shape.Size Allows you to specify the shape's width and height.

The following code creates a rectangle and specifies its height and width:

Document document = richEditControl.Document;
// Set the measurement unit to inches.
document.Unit = DevExpress.Office.DocumentUnit.Inch;
// Create a rectangle.
Shape rectangle = document.Shapes.InsertShape(document.Range.Start, ShapeGeometryPreset.Rectangle);
// Specify its width and height.
rectangle.Width = 2;
rectangle.Height = 1;

Relative Size

Property Description
Shape.HeightRelative Specifies the shape's height (as a percentage) relative to the element defined by the RelativeVerticalSize property.
Shape.WidthRelative Specifies the shape's width (as a percentage) relative to the element defined by the RelativeHorizontalSize property.
Shape.SizeRelative Allows you to specify the shape's relative width and height.

The following example creates a rectangle and sets its width and height to 50% of the page size:

Document document = richEditControl.Document;
// Create a rectangle.
Shape rectangle = document.Shapes.InsertShape(document.Range.Start, ShapeGeometryPreset.Rectangle);
// Set the rectangle width to 50% of the page width.
rectangle.RelativeHorizontalSize = ShapeRelativeHorizontalSize.Page;
rectangle.WidthRelative = 0.5f;
// Set the rectangle height to 50% of the page height.
rectangle.RelativeVerticalSize = ShapeRelativeVerticalSize.Page;
rectangle.HeightRelative = 0.5f;

Scale Factor

Property Description
Shape.ScaleX Scales a shape horizontally relative to its original size.
Shape.ScaleY Scales a shape vertically relative to its original size.

The following example resizes all pictures in the document:

document.LoadDocument("FirstLook.docx", DevExpress.XtraRichEdit.DocumentFormat.OpenXml);
foreach (Shape s in document.Shapes)
{
    // Scale pictures.
    if (s.Type == ShapeType.Picture)
    {
        s.ScaleX = 0.8f;
        s.ScaleY = 0.8f;
    }
}

Lock Aspect Ratio

Set the Shape.LockAspectRatio property to true to resize a shape proportionally.

Rotate Shapes

Use the Shape.RotationAngle property to rotate a shape.

The example below rotates all pictures in the document.

Rotate pictures

document.LoadDocument("FirstLook.docx", DevExpress.XtraRichEdit.DocumentFormat.OpenXml);
foreach (Shape s in document.Shapes)
{
    // Rotate pictures.
    if (s.Type == ShapeType.Picture)
    {
        s.RotationAngle = 45;
    }
}

Group Shapes

Call the ShapeCollection.InsertGroup method to create a shape group. The Shape.GroupItems property returns a collection of group elements. Use the collection's Add methods to add nested groups, shapes, and pictures to the group.

NOTE

You cannot group shapes that already exist in a document.

The example below creates a shape group in the document.

Add a group to ShapeCollection

Document document = richEditControl.Document;
// Set the measurement unit to inches.
document.Unit = DevExpress.Office.DocumentUnit.Inch;
// Insert a shape group.
Shape group = document.Shapes.InsertGroup(document.Range.Start);
// Specify the group position relative to the left and top edges of the page. 
group.Offset = new PointF(1.5f, 1f);
// Access the collection of group items. 
var groupItems = group.GroupItems;
// Add a rectangle to the group.
var shape1 = groupItems.AddShape(ShapeGeometryPreset.Rectangle, new RectangleF(0f, 0f, 2f, 1.5f));
shape1.Fill.SetSolidFill(Color.FromArgb(0xA4, 0xFF, 0xFF));
shape1.Line.Color = Color.DarkGray;
shape1.Line.Thickness = 2;
// Add a picture to the group.
var shape2 = groupItems.AddPicture(DocumentImageSource.FromFile("Picture_Arrow.png"), new PointF(2.1f, 0.3f));
// Add a parallelogram to the group.
var shape3 = groupItems.AddShape(ShapeGeometryPreset.Parallelogram, new RectangleF(3.8f, 0f, 2f, 1.5f));
shape3.Fill.SetSolidFill(Color.FromArgb(0xFF, 0xA5, 0xA5));
shape3.Line.Color = Color.DarkGray;
shape3.Line.Thickness = 2;

Ungroup Shapes

Use the Shape.GroupItems.Ungroup method to split an existing shape group into individual drawing objects.

The example below shows how to split all shape groups in the document (including nested groups):

using System.Linq;
// ...

Document document = richEditControl.Document;
List<DrawingObject> groups = document.Shapes.Flatten()
    .Where(x => x.Type == ShapeType.Group)
    .ToList();
for (int i = groups.Count - 1; i >= 0; i--)
{
    groups[i].GroupItems.Ungroup();
}

Use the following API to attach a hyperlink to a shape:

Member Description
Shape.AddHyperlink Creates a new Hyperlink object associated with a shape.
Hyperlink.NavigateUri Specifies the hyperlink's destination.
Hyperlink.ToolTip Adds a tooltip to the hyperlink. This text is displayed when the mouse pointer hovers over the shape.

The following example inserts a picture and attaches a hyperlink to it:

XtraRichEdit_HyperlinkPicture

Document document = richEditControl.Document;
Shape picture = document.Shapes.InsertPicture(document.Range.Start, DocumentImageSource.FromFile("DevExpress.png"));
Hyperlink pictureHyperlink = picture.AddHyperlink();
pictureHyperlink.NavigateUri = "https://community.devexpress.com/blogs/";
pictureHyperlink.ToolTip = "Check the recent DevExpress blogs";

Remove Shapes

Use one of the following methods to remove a shape from the document:

Document document = richEditControl.Document;
// Access the shape collection.
ShapeCollection shapes = document.Shapes;

// Delete the first shape from the collection.
shapes.RemoveAt(0);

// Delete the "Rectangle 1" shape.
shapes.Remove(shapes["Rectangle 1"]);