---
title: "How to Use Vector Objects"
canonical: https://www.graphicsmill.com/docs/gm5/HowToUseVectorObjects.htm
product: "Graphics Mill 5.5 for .NET"
---

This documentation is for the old version. [Go to the latest Graphics Mill docs](https://www.graphicsmill.com/docs/gm/)

# How to Use Vector Objects
 
This topic describes how to use the Vector Objects module in more complex applications that the one described in the [Quick Start in Vector Objects](https://www.graphicsmill.com/docs/gm5/QuickStartinVectorObjects.htm.md) topic. This text is based on the code of the [Multilayer Image Editor](https://www.graphicsmill.com/docs/gm5/WinSamples.htm.md) sample. The intention of this sample is to provide guidelines on working with the Vector Objects module and to demonstrate how to create a simple custom v-object.
 
The main part of this sample is the [MultiLayerViewer](https://www.graphicsmill.com/docs/gm5/T_Aurigma_GraphicsMill_WinControls_MultiLayerViewer.htm.md) control itself. All objects available for user manipulation—both layers and v-objects— are hosted by this control. The control provides alsmost all features used and demonstrated in the sample. For better understanding of the control architecture, refer to the [Basic Concepts of Vector Objects](https://www.graphicsmill.com/docs/gm5/BasicConceptsOfVectorObjects.htm.md) topic.
 
## User Interface Overview
  
The user interface of this application consists of four main parts:
 
- *Toolbar* contains buttons to add vector objects and turn on/off such v-object actions as rotate and resize.
- *Viewport* area contains the image itself.
- *Layers list* contains a list of layers and buttons to add, remove, rename and swap layers.
- *Objects list* is located under the Layers list contains a list of vector objects of the current layer. It also has buttons to remove, rename and swap objects.

![Multilayer Image Editor screenshot](https://www.graphicsmill.com/docs/gm5/HowToUseVectorObjects.png) 
 **Fig. 1. Multilayer Image Editor screenshot**
 
## V-objects Usage
  
In this sample, the following operations with v-objects are shown.
 
### Adding and Removing V-objects
 
When the user clicks one of the Add buttons on the toolbar, the AddNewObject method is called. This method takes as an argument one of  XXXCreateDesigner objects—depending on the type of the v-object being created. For example, if the user clicks the Add New Image button, [ImageVObjectCreateDesigner](https://www.graphicsmill.com/docs/gm5/T_Aurigma_GraphicsMill_WinControls_ImageVObjectCreateDesigner.htm.md) will be passed to the AddNewObject method.  XXXCreateDesigner objects are used in order to let the user select the part of the viewer area where a new v-object will be placed. Here is an implementation of the AddNewObject method:
 
```
Private Sub AddNewObject(ByVal designer As Aurigma.GraphicsMill.WinControls.IDesigner)
    If _multiLayerViewer.CurrentLayer Is Nothing Then
        
        'Do not allow adding objects, if no layer is selected
        ClearAddObjectToggle()
        Return
    End If
    If _multiLayerViewer.Layers(_layersCheckedListBox.SelectedIndex).Visible = _
        False Then
    
        'Do not allow adding objects, if the selected layer is hidden
        ClearAddObjectToggle()
        Return
    End If
    If _multiLayerViewer.Layers.Count < 1 Then
    
        'Do not allow adding objects, if no layers exist
        ClearAddObjectToggle()
        Return
    End If

    'If the desginer needs to load a bitmap, open the file choose dialog
    If TypeOf designer Is Aurigma.GraphicsMill.WinControls.ImageVObjectCreateDesigner Then
        Dim imageDesigner As Aurigma.GraphicsMill.WinControls.ImageVObjectCreateDesigner = _
            CType(designer, Aurigma.GraphicsMill.WinControls.ImageVObjectCreateDesigner)
        If _imageOpenFileDialog.ShowDialog = DialogResult.OK Then
            Try
                imageDesigner.Bitmap = New Aurigma.GraphicsMill.Bitmap( _
                    _imageOpenFileDialog.FileName)
            Catch ex As Exception
                MessageBox.Show(ex.Message, "Load Image Error", _
                    MessageBoxButtons.OK, MessageBoxIcon.Error)
                _addImageToolBarButton.Pushed = False
                Return
            End Try
        End If
        ClearAddObjectToggle(Nothing)
    End If

    'Set the current designer
    _multiLayerViewer.CurrentDesigner = designer
End Sub
```
 
```csharp
private void AddNewObject(Aurigma.GraphicsMill.WinControls.IDesigner designer)
{
    if (_multiLayerViewer.CurrentLayer == null)
    {
        //Do not allow adding objects, if no layer is selected
        ClearAddObjectToggle();
        return;
    }
    if (_multiLayerViewer.Layers[_layersCheckedListBox.SelectedIndex].Visible ==
        false)
    {
        //Do not allow adding objects, if the selected layer is hidden
        ClearAddObjectToggle();
        return;
    }
    if (_multiLayerViewer.Layers.Count < 1)
    {
        //Do not allow adding objects, if no layers exist
        ClearAddObjectToggle();
        return;
    }
    
    //If the desginer needs to load a bitmap, open the file choose dialog
    if (designer is Aurigma.GraphicsMill.WinControls.ImageVObjectCreateDesigner)
    {
        Aurigma.GraphicsMill.WinControls.ImageVObjectCreateDesigner imageDesigner =
            (Aurigma.GraphicsMill.WinControls.ImageVObjectCreateDesigner) designer;
        if (_imageOpenFileDialog.ShowDialog() == DialogResult.OK)
        {
            try
            {
                imageDesigner.Bitmap = new Aurigma.GraphicsMill.Bitmap(
                    _imageOpenFileDialog.FileName);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Load Image Error",
                MessageBoxButtons.OK, MessageBoxIcon.Error);
                _addImageToolBarButton.Pushed = false;
                return;
            }
        }
        ClearAddObjectToggle(null);
    }
    
    //Set the current designer
    _multiLayerViewer.CurrentDesigner = designer;
}
```
 
When the user selects objects to delete in the Objects list and the clicks the Remove Objects button, the RemoveObject method is called for each selected object. This method, in turn, simply calls the [VObjectCollection.Remove](https://www.graphicsmill.com/docs/gm5/O_T_Aurigma_GraphicsMill_WinControls_VObjectCollection_Remove.htm.md) method:
 
```
Private Sub RemoveObject(ByVal obj As Aurigma.GraphicsMill.WinControls.IVObject)
    _multiLayerViewer.CurrentLayer.VObjects.Remove(obj)
End Sub
```
 
```csharp
private void RemoveObject(Aurigma.GraphicsMill.WinControls.IVObject obj)
{
    _multiLayerViewer.CurrentLayer.VObjects.Remove(obj);
}
```
 
### Changing V-object Properties
 
In this demo application the user can change settings (if available) of the selected v-object, for example: select a pen to outline the object and a brush to fill it. Changing these settings itself is not really interesting as you simply need to assign required values to the [Pen](https://www.graphicsmill.com/docs/gm5/P_Aurigma_GraphicsMill_WinControls_PathVObject_Pen.htm.md) and [Brush](https://www.graphicsmill.com/docs/gm5/P_Aurigma_GraphicsMill_WinControls_PathVObject_Brush.htm.md) properties of the selected v-object. The interesting part is that the dialog from which the user chooses required colors is opened through a context menu of the v-object.
 
This context menu is a standard Windows Forms control. Work with it as with any other context menu. The only particular thing you need to do is to attach the menu to the current designer as this designer represents the currently selected object. Below is a method that sets the appropriate menu based on the type of the selected object. This method should be called when the current designer is somehow changed:
 
```
Private Sub UpdateVObjectContextMenu(ByVal obj As Aurigma.GraphicsMill.WinControls.VObject)
    Dim designer As Aurigma.GraphicsMill.WinControls.GenericVObjectEditDesigner = _
    CType(obj.Designer, Aurigma.GraphicsMill.WinControls.GenericVObjectEditDesigner)

    If TypeOf obj Is Aurigma.GraphicsMill.WinControls.RectangleVObject Then
        designer.ContextMenu = _penBrushSettingsContextMenu
    ElseIf TypeOf obj Is Aurigma.GraphicsMill.WinControls.EllipseVObject Then
        designer.ContextMenu = _penBrushSettingsContextMenu
    ElseIf TypeOf obj Is Aurigma.GraphicsMill.WinControls.LineVObject Then
        designer.ContextMenu = _penSettingsContextMenu
    ElseIf TypeOf obj Is Aurigma.GraphicsMill.WinControls.PolylineVObject Then
        designer.ContextMenu = _penBrushSettingsContextMenu
    ElseIf TypeOf obj Is Aurigma.GraphicsMill.WinControls.TextVObject Then
        designer.ContextMenu = _textSettingsContextMenu
    End If
End Sub
```
 
```csharp
private void UpdateVObjectContextMenu(Aurigma.GraphicsMill.WinControls.VObject obj)
{
    Aurigma.GraphicsMill.WinControls.GenericVObjectEditDesigner designer =
        (Aurigma.GraphicsMill.WinControls.GenericVObjectEditDesigner)
        obj.Designer;
    
    if (obj is Aurigma.GraphicsMill.WinControls.RectangleVObject)
    {
        designer.ContextMenu = _penBrushSettingsContextMenu;
    }
    else if (obj is Aurigma.GraphicsMill.WinControls.EllipseVObject)
    {
        designer.ContextMenu = _penBrushSettingsContextMenu;
    }
    else if (obj is Aurigma.GraphicsMill.WinControls.LineVObject)
    {
        designer.ContextMenu = _penSettingsContextMenu;
    }
    else if (obj is Aurigma.GraphicsMill.WinControls.PolylineVObject)
    {
        designer.ContextMenu = _penBrushSettingsContextMenu;
    }
    else if (obj is Aurigma.GraphicsMill.WinControls.TextVObject)
    {
        designer.ContextMenu = _textSettingsContextMenu;
    }
}
```
 
### Actions
 
The user can also transform objects—rotate, skew and resize—by dragging the corresponding control points. In terms of Vector Objects such transformations made by the user are called *actions*. In this demo the user can also turn these actions on and off by clicking buttons on the toolbar. When the user clicks a toggle button that enables or disables some action, action grips (they are the corresponding control points) either become visible or hidden.
 
Different v-objects can support different actions. If you need to know which actions are supported by a particular v-object, check its [VObject.SupportedActions](https://www.graphicsmill.com/docs/gm5/P_Aurigma_GraphicsMill_WinControls_VObject_SupportedActions.htm.md) collection. Each action in this collection is represented by a constant value. Using this value you can create a required action object, a descendant of the [VObjectAction](https://www.graphicsmill.com/docs/gm5/T_Aurigma_GraphicsMill_WinControls_VObjectAction.htm.md) class. This newly created object will have the [Enabled](https://www.graphicsmill.com/docs/gm5/P_Aurigma_GraphicsMill_WinControls_VObjectAction_Enabled.htm.md) property. When this property is set to `false` object designers will not allow applying the corresponding action.
 
In Multilayer Image Editor, actions are enabled of disabled depending on the state of toggle buttons:
 
```
If Not _multiLayerViewer.CurrentDesigner Is Nothing AndAlso _
    _multiLayerViewer.CurrentDesigner.VObjects.Length > 0 Then
    For Each obj As Aurigma.GraphicsMill.WinControls.IControlPointsProvider In _
        _multiLayerViewer.CurrentDesigner.VObjects

        If obj.SupportedActions.Contains(Aurigma.GraphicsMill.WinControls.VObjectAction.Resize) Then
        
            'Enable or disable resize
            obj.SupportedActions(Aurigma.GraphicsMill.WinControls.VObjectAction.Resize).Enabled = _
                _resizeGripsToolBarButton.Pushed
        End If

        If obj.SupportedActions.Contains(Aurigma.GraphicsMill.WinControls.VObjectAction.Rotate) Then
            
            'Enable or disable rotate
            obj.SupportedActions(Aurigma.GraphicsMill.WinControls.VObjectAction.Rotate).Enabled = _
                _rotateGripsToolBarButton.Pushed
        End If

        If obj.SupportedActions.Contains(Aurigma.GraphicsMill.WinControls.VObjectAction.Skew) Then
            
            'Enable or disable skew
            obj.SupportedActions(Aurigma.GraphicsMill.WinControls.VObjectAction.Skew).Enabled = _
                _skewGripsToolBarButton.Pushed
        End If
    Next
End If
```
 
```csharp
if (_multiLayerViewer.CurrentDesigner != null &&
    _multiLayerViewer.CurrentDesigner.VObjects.Length > 0)
{
    foreach (Aurigma.GraphicsMill.WinControls.IControlPointsProvider obj in
        _multiLayerViewer.CurrentDesigner.VObjects)
    {
        if (obj.SupportedActions.Contains(
            Aurigma.GraphicsMill.WinControls.VObjectAction.Resize))
        {
            //Enable or disable resize
            obj.SupportedActions[Aurigma.GraphicsMill.WinControls.VObjectAction.Resize].Enabled =
                _resizeGripsToolBarButton.Pushed;
        }
        
        if (obj.SupportedActions.Contains(
        Aurigma.GraphicsMill.WinControls.VObjectAction.Rotate))
        {
            //Enable or disable rotate
            obj.SupportedActions[Aurigma.GraphicsMill.WinControls.VObjectAction.Rotate].Enabled =
                _rotateGripsToolBarButton.Pushed;
        }
        
        if (obj.SupportedActions.Contains(Aurigma.GraphicsMill.WinControls.VObjectAction.Skew))
        {
            //Enable or disable skew
            obj.SupportedActions[Aurigma.GraphicsMill.WinControls.VObjectAction.Skew].Enabled =
                _skewGripsToolBarButton.Pushed;
        }
    }
}
```
 
## Layers Usage
  
Another feature of the MultiLayerViewer control is work with layers. That is probably one of the simplest things. As described in the [Basic Concepts of Vector Objects](https://www.graphicsmill.com/docs/gm5/BasicConceptsOfVectorObjects.htm.md) topic, layers are organized in an array associated with the control. This array can be accessed using the [IVObjectHost.Layers](https://www.graphicsmill.com/docs/gm5/P_Aurigma_GraphicsMill_WinControls_IVObjectHost_Layers.htm.md) property. So, if you want to add, remove or reorganize layers, just add, remove or reorganize the items of this array. Here is how you can delete a layer:
 
```
Private Sub RemoveLayer(ByVal layer As Aurigma.GraphicsMill.WinControls.Layer)
    _multiLayerViewer.Layers.Remove(layer)
    If _layersCheckedListBox.Items.Count < 1 Then
        _layerRemoveToolBarButton.Enabled = False
        _layerRenameToolBarButton.Enabled = False
        _layerRemoveMenuItem.Enabled = False
        _layerRenameMenuItem.Enabled = False
    End If
End Sub
```
 
```csharp
private void RemoveLayer(Aurigma.GraphicsMill.WinControls.Layer layer)
{
    _multiLayerViewer.Layers.Remove(layer);
    if (_layersCheckedListBox.Items.Count < 1)
    {
        _layerRemoveToolBarButton.Enabled = false;
        _layerRenameToolBarButton.Enabled = false;
        _layerRemoveMenuItem.Enabled = false;
        _layerRenameMenuItem.Enabled = false;
    }
}
```
 
If you want to lock, rename the layer or toggle its visibility, set the needed value of the [Locked](https://www.graphicsmill.com/docs/gm5/P_Aurigma_GraphicsMill_WinControls_Layer_Locked.htm.md), [Visible](https://www.graphicsmill.com/docs/gm5/P_Aurigma_GraphicsMill_WinControls_Layer_Visible.htm.md) or [Name](https://www.graphicsmill.com/docs/gm5/P_Aurigma_GraphicsMill_WinControls_Layer_Name.htm.md) property of the selected layer, as in the following example:
 
```
Private Sub RenameLayer(ByVal layer As Aurigma.GraphicsMill.WinControls.Layer)
    _changeNameDialog.Value = layer.Name
    If _changeNameDialog.ShowDialog = DialogResult.OK Then
        layer.Name = _changeNameDialog.Value
        UpdateLayersListBox()
    End If
End Sub
```
 
```csharp
private void RenameLayer(Aurigma.GraphicsMill.WinControls.Layer layer)
{
    _changeNameDialog.Value = layer.Name;
    if (_changeNameDialog.ShowDialog() == DialogResult.OK)
    {
        layer.Name = _changeNameDialog.Value;
        UpdateLayersListBox();
    }
}
```
 
## Undo and Redo
  
One more convenient and easy-to-use feature of the MultiLayerViewer control is support for undoing and redoing changes. So, what should happen when the user clicks Undo or Redo in the Edit menu? Well, you should simply call the [MultiLayerViewer.Undo](https://www.graphicsmill.com/docs/gm5/O_T_Aurigma_GraphicsMill_WinControls_MultiLayerViewer_Undo.htm.md) or [MultiLayerViewer.Redo](https://www.graphicsmill.com/docs/gm5/O_T_Aurigma_GraphicsMill_WinControls_MultiLayerViewer_Redo.htm.md) method and update the user interface:
 
```
Private Sub Undo()
    _multiLayerViewer.Undo()
    If Not _multiLayerViewer.CanUndo Then
        _undoToolBarButton.Enabled = False
        _undoMenuItem.Enabled = False
    End If
    _redoToolBarButton.Enabled = True
    _redoMenuItem.Enabled = True
End Sub

Private Sub Redo()
    _multiLayerViewer.Redo()
    If Not _multiLayerViewer.CanRedo Then
        _redoToolBarButton.Enabled = False
        _redoMenuItem.Enabled = False
    End If
    _undoToolBarButton.Enabled = True
    _undoMenuItem.Enabled = True
End Sub
```
 
```csharp
private void Undo()
{
    _multiLayerViewer.Undo();
    if (! _multiLayerViewer.CanUndo)
    {
        _undoToolBarButton.Enabled = false;
        _undoMenuItem.Enabled = false;
    }
    _redoToolBarButton.Enabled = true;
    _redoMenuItem.Enabled = true;
}

private void Redo()
{
    _multiLayerViewer.Redo();
    if (! _multiLayerViewer.CanRedo)
    {
        _redoToolBarButton.Enabled = false;
        _redoMenuItem.Enabled = false;
    }
    _undoToolBarButton.Enabled = true;
    _undoMenuItem.Enabled = true;
}
```
 
All the rest is already done for you.
 
## Opening and Saving Files
  
### Saving and Opening Layered Images
 
This application demonstrates how one can save a layered drawing in a file and later open it for additional editing.
 
When the user clicks Save in the File menu, they can save the their drawing in a data file (DAT). When the image is saved in a DAT file, it is actually *serialized*. That is, its data are written in some format that can be read later. To save the image data, you need to serialize the MultiLayerViewer properties and then all the layers associated with it. When the layers are saved this way, it also serializes all contained objects. Here is how you can save a layered drawing to a DAT file:
 
```
Private Sub SaveTemplateToFile(ByVal fileName As String)
    Dim file As New System.IO.FileStream(fileName, System.IO.FileMode.Create, _
        System.IO.FileAccess.Write)
    Dim formatter As New _
        System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
    formatter.Serialize(file, _multiLayerViewer.WorkspaceWidth)
    formatter.Serialize(file, _multiLayerViewer.WorkspaceHeight)
    _multiLayerViewer.Layers.Serialize(file)
    file.Close()
End Sub
```
 
```csharp
private void SaveTemplateToFile(string fileName)
{
    System.IO.FileStream file = new System.IO.FileStream(fileName,
        System.IO.FileMode.Create, System.IO.FileAccess.Write);
    System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter =
        new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
    formatter.Serialize(file, _multiLayerViewer.WorkspaceWidth);
    formatter.Serialize(file, _multiLayerViewer.WorkspaceHeight);
    
    _multiLayerViewer.Layers.Serialize(file);
    file.Close();
}
```
 
**Important** 
Remember that binary format used for serialization is highly dependent on the build version, as the API may change from version to version, and properties may be added or removed.
 
If you need to later open a DAT file with the image, deserialize the MultiLayerViewer properties and the layers:
 
```
Private Sub OpenTemplateFromFile(ByVal fileName As String)
    Dim file As System.IO.FileStream = Nothing
    Try
        file = New System.IO.FileStream(fileName, System.IO.FileMode.Open, _
            System.IO.FileAccess.Read)

        Dim formatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
        _multiLayerViewer.WorkspaceWidth = CType(formatter.Deserialize(file), _
            System.Int32)
        _multiLayerViewer.WorkspaceHeight = CType(formatter.Deserialize(file), _
            System.Int32)

        _multiLayerViewer.Layers.Deserialize(file)
        _multiLayerViewer.ClearHistory()
        _undoMenuItem.Enabled = False
        _redoMenuItem.Enabled = False
        _undoToolBarButton.Enabled = False
        _redoToolBarButton.Enabled = False
    Catch ex As Exception
        System.Windows.Forms.MessageBox.Show("Cannot load specified file.", _
            "Opening file error", MessageBoxButtons.OK, MessageBoxIcon.Error)
    Finally
        If Not file Is Nothing Then file.Close()
    End Try

    '...Update the rest of GUI...
End Sub
```
 
```csharp
private void OpenTemplateFromFile(string fileName)
{
    System.IO.FileStream file = null;
    try
    {
        file = new System.IO.FileStream(fileName, System.IO.FileMode.Open,
            System.IO.FileAccess.Read);
        
        System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter =
            new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
        _multiLayerViewer.WorkspaceWidth = (int)formatter.Deserialize(file);
        _multiLayerViewer.WorkspaceHeight = (int)formatter.Deserialize(file);
        
        _multiLayerViewer.Layers.Deserialize(file);
        _multiLayerViewer.ClearHistory();
        _undoMenuItem.Enabled = false;
        _redoMenuItem.Enabled = false;
        _undoToolBarButton.Enabled = false;
        _redoToolBarButton.Enabled = false;
    }
    catch (Exception)
    {
        System.Windows.Forms.MessageBox.Show("Cannot load specified file.",
            "Opening file error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    finally
    {
        if (file != null)
        {
            file.Close();
        }
    }
    
    //...Update the rest of GUI...
}
```
 
### Rendering a Bitmap
 
The user can also save the image as a bitmap in one of the graphic formats supported by Graphics Mill for .NET. To implement this feature, you will only need to call the [MultiLayerViewer.RenderWorkspace](https://www.graphicsmill.com/docs/gm5/O_T_Aurigma_GraphicsMill_WinControls_MultiLayerViewer_RenderWorkspace.htm.md) method and save the image to a bitmap:
 
```
Private Sub Render()
    If _resultSaveFileDialog.ShowDialog = DialogResult.OK Then
        _renderForm.WidthValue = _multiLayerViewer.WorkspaceWidth
        If _renderForm.ShowDialog = DialogResult.OK Then
            Try
                Dim bitmap As Aurigma.GraphicsMill.Bitmap = _
                    _multiLayerViewer.RenderWorkspace()
                bitmap.Save(_resultSaveFileDialog.FileName)
                bitmap.Dispose()
            Catch ex As ArgumentOutOfRangeException
                MessageBox.Show("Width and height of the image should be above zero.", _
                    "Image Save Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Catch ex As Exception
                MessageBox.Show(ex.Message, "Image Save Error", _
                    MessageBoxButtons.OK, MessageBoxIcon.Error)
            End Try
        End If
    End If
End Sub
```
 
```csharp
private void Render()
{
    if (_resultSaveFileDialog.ShowDialog() == DialogResult.OK)
    {
        _renderForm.WidthValue = _multiLayerViewer.WorkspaceWidth;
        if (_renderForm.ShowDialog() == DialogResult.OK)
        {
            try
            {
                Aurigma.GraphicsMill.Bitmap bitmap =
                    _multiLayerViewer.RenderWorkspace();
                bitmap.Save(_resultSaveFileDialog.FileName);
                bitmap.Dispose();
            }
            catch (ArgumentOutOfRangeException)
            {
                MessageBox.Show("Width and height of the image should be above zero.",
                    "Image Save Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Image Save Error",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }
}
```
 
## Creating a Custom V-object
  
As an example of a custom v-object implementation, this demo contains an object that fills the background of the layer with some color. Each custom object should implement the [IVObject](https://www.graphicsmill.com/docs/gm5/T_Aurigma_GraphicsMill_WinControls_IVObject.htm.md) interface that provides basic required members. If you want to let the user transform your v-object, you should also implement the [IControlPointsProvider](https://www.graphicsmill.com/docs/gm5/T_Aurigma_GraphicsMill_WinControls_IControlPointsProvider.htm.md) interface.The easiest way to meet these conditions is to inherit from the [VObject](https://www.graphicsmill.com/docs/gm5/T_Aurigma_GraphicsMill_WinControls_VObject.htm.md) class and to override the members that need modifications.
 
The sample custom v-object, SolidBackgroundVObject, overrides only several methods from the IVObject interface, as rotate, skew or resize (for which the IControlPointsProvider is intended) are not applicable for this kind of objects. This custom v-object also implements the ISerialization interface which allows saving this object along with other layer objects. A full listing of this v-object implementation can be found in the SolidBackgroundVObject.cs file of the [Multi-layer image editor demo](https://www.graphicsmill.com/docs/gm5/WinSamples.htm.md).
 
Also, an example implementation of the corresponding designer, SolidBackgroundVObjectCreateDesigner, is provided in the SolidBackgroundVObjectCreateDesigner.cs file of the same demo. This designer is used to make a new v-object, that fills the whole viewer area, and to put it behind all other objects in a layer.
 
## See Also
  
### Reference
 
- [MultiLayerViewer Class](https://www.graphicsmill.com/docs/gm5/T_Aurigma_GraphicsMill_WinControls_MultiLayerViewer.htm.md)
- [ImageVObjectCreateDesigner Class](https://www.graphicsmill.com/docs/gm5/T_Aurigma_GraphicsMill_WinControls_ImageVObjectCreateDesigner.htm.md)
- [VObjectCollection.Remove Overload](https://www.graphicsmill.com/docs/gm5/O_T_Aurigma_GraphicsMill_WinControls_VObjectCollection_Remove.htm.md)
- [PathVObject.Pen Property](https://www.graphicsmill.com/docs/gm5/P_Aurigma_GraphicsMill_WinControls_PathVObject_Pen.htm.md)
- [PathVObject.Brush Property](https://www.graphicsmill.com/docs/gm5/P_Aurigma_GraphicsMill_WinControls_PathVObject_Brush.htm.md)
- [VObjectAction.Enabled Property](https://www.graphicsmill.com/docs/gm5/P_Aurigma_GraphicsMill_WinControls_VObjectAction_Enabled.htm.md)
- [VObject.SupportedActions Property](https://www.graphicsmill.com/docs/gm5/P_Aurigma_GraphicsMill_WinControls_VObject_SupportedActions.htm.md)
- [Layer.Locked Property](https://www.graphicsmill.com/docs/gm5/P_Aurigma_GraphicsMill_WinControls_Layer_Locked.htm.md)
- [Layer.Visible Property](https://www.graphicsmill.com/docs/gm5/P_Aurigma_GraphicsMill_WinControls_Layer_Visible.htm.md)
- [Layer.Name Property](https://www.graphicsmill.com/docs/gm5/P_Aurigma_GraphicsMill_WinControls_Layer_Name.htm.md)
- [MultiLayerViewer.Undo Overload](https://www.graphicsmill.com/docs/gm5/O_T_Aurigma_GraphicsMill_WinControls_MultiLayerViewer_Undo.htm.md)
- [MultiLayerViewer.Redo Overload](https://www.graphicsmill.com/docs/gm5/O_T_Aurigma_GraphicsMill_WinControls_MultiLayerViewer_Redo.htm.md)
- [IVObject Class](https://www.graphicsmill.com/docs/gm5/T_Aurigma_GraphicsMill_WinControls_IVObject.htm.md)
- [IControlPointsProvider Class](https://www.graphicsmill.com/docs/gm5/T_Aurigma_GraphicsMill_WinControls_IControlPointsProvider.htm.md)
- [VObject Class](https://www.graphicsmill.com/docs/gm5/T_Aurigma_GraphicsMill_WinControls_VObject.htm.md)

### Manual
 
- [Windows Controls Samples](https://www.graphicsmill.com/docs/gm5/WinSamples.htm.md)
- [Basic Concepts of Vector Objects](https://www.graphicsmill.com/docs/gm5/BasicConceptsOfVectorObjects.htm.md)
