Search
Styles and Themes

The style and theme system provides a consistent way to customize the appearance of a Diagram and its items. By using styles and themes, it is easier to achieve coherent look and feel across the entire diagram. In addition, changing the look and feel can be achieved by simply replacing the current theme.

Styles

The style is a set of properties. Styles can be applied to diagrams and individual diagram items and this can potentially affect the values of some properties of the target object. More specifically, if the value of a style-affected property in the target object is null, then the value is obtained from the associated style. The style does not necessarily need to provide values for all of its properties. If a styled property is null and it is not defined in the associated style, the style system searches for a value in the current theme. A complete value precedence list can be found later in this topic.

The styles are represented by the Style class and its various subclasses. Styles can be applied to diagram objects through the Style property of the Diagram class and to diagram items through the Style property of the DiagramItem class. Styles can also participate in themes, in which case they affect all objects of specific type.

Themes

The theme is a set of styles, each associated with specific diagram or item type. When the theme is applied to a diagram, the styles registered in the theme affect all objects of their associated type.

Themes are represented by the Theme class and can be assigned to Diagram objects through the Theme property. Styles are associated with types within the theme through the RegisterStyle method. The following code creates a new theme, with a single style for ShapeNode items and applies this theme to an existing diagram.

C#  Copy Code

var theme = new Theme();
var style = new ShapeNodeStyle();
style.FontFamily = "Courier New";
theme.RegisterStyle(typeof(ShapeNode), style);
diagram.Theme = theme;

VB.NET  Copy Code

Dim theme As New Theme()
Dim style As New ShapeNodeStyle()
style.FontFamily = "Courier New"
theme.RegisterStyle(GetType(ShapeNode), style)
diagram.Theme = theme

Alternatively, themes can be loaded from XML files by calling the LoadFromXml method. Such XML files can be produced by the Theme Editor tool, or by calling the SaveToXml method of an existing theme.

Value Precedence

The style and theme system is hierarchical. This means that, when a value of a styled property is requested, the system starts searching for this value along a chain of defined styles. The system returns the first valid value encountered. If no valid value is encountered along the chain, the system returns a globally defined default value for the property. The following list explains the search order in more details:

  1. If the local value of the object is not null, the local value is returned.
  2. If the object has a style and the property in this style has value, this value is returned.
  3. If the object is an item, which is part of a diagram, the local style of the diagram is searched.
  4. If the object is an item, which is part of a diagram and the diagram has associated theme, the theme is searched for styles registered for the item's type or its base types. If a style with a defined property value is found, this value is returned.
  5. Similar search as the previous one is performed for a theme-registered style for the Diagram class.
  6. If the above steps do not produce value; the system returns a globally define default for the property.

For example, if the effective value of the text brush property of a ShapeNode is requested (through the EffectiveTextBrush property), the style system performs the following search, according to the above rules:

  1. If ShapeNode.TextBrush is not nullShapeNode.TextBrush is returned.
  2. If ShapeNode.Style is set and the DiagramItemStyle.TextBrush property in this style has value, this value is returned.
  3. If the node is part of a diagram, the Diagram.Style is set, and the DiagramStyle.TextBrush property of this style has value, this value is returned.
  4. If the node is part of a diagram and the Diagram.Theme is set, the theme is searched for a style registered for the ShapeNode type. If there is such style and its DiagramItemStyle.TextBrush property has value, this value is returned.
  5. Similar search as the previous one is performed for a theme-registered style for the Diagram type.
  6. Finally, the system returns a globally-defined default value for the TextBrush property (which is a solid Black brush).

Custom Styles

The following section describes how to enable styling for properties of custom item classes. To enable styling, create a custom style class by deriving from the closest existing type. For example, for a custom ShapeNode (say, MyNode), the custom style needs to inherit from ShapeNodeStyle:

C#  Copy Code

public class MyNodeStyle : ShapeNodeStyle
{
}

Visual Basic  Copy Code

Public Class MyNodeStyle
    Inherits ShapeNodeStyle

End Class

For each property in MyNode that needs to be styled, define a property with the same name and type in the MyNodeStyle class by following the pattern below. For example, if MyNode contains a property MyBrush of type Brush, the following code defines its corresponding style property:

C#  Copy Code

public class MyNodeStyle : ShapeNodeStyle
{
    public MyNodeStyle()
    {
        myBrushProperty = RegisterProperty("MyBrush");
    }

    public Brush MyBrush
    {
        get { return (Brush)GetValue(myBrushProperty); }
        set { SetValue(myBrushProperty, value); }
    }

    private object myBrushProperty;
}

Visual Basic  Copy Code

Public Class MyNodeStyle
    Inherits ShapeNodeStyle

    Public Sub New()
        myBrushProperty = RegisterProperty("MyBrush")
    End Sub

    Public Property MyBrush() As Brush
        Get
            Return DirectCast(GetValue(myBrushProperty), Brush)
        End Get
        Set
            SetValue(myBrushProperty, value)
        End Set
    End Property

    Private myBrushProperty As Object

End Class

Now, in the custom MyNode class, define a new property, EffectiveMyBrush, which will return the actual value of MyBrush:

C#  Copy Code

public Brush EffectiveMyBrush
{
    get
    {
        // Checking for local value
        if (MyBrush != null)
            return MyBrush;
        // Querying the property value through the style system
        return (Brush)GetValue("MyBrush");
    }
}

Visual Basic  Copy Code

Public ReadOnly Property EffectiveMyBrush() As Brush

    Get

        ' Checking for local value
        If MyBrush IsNot Nothing Then
            Return MyBrush
        End If
        ' Querying the property value through the style system
        Return DirectCast(GetValue("MyBrush"), Brush)

    End Get

End Property

Remember to register the style class for serialization, along with the custom node class:

C#  Copy Code

Diagram.RegisterClass(typeof(MyNode), "MyNode", 1);
Diagram.RegisterClass(typeof(MyNodeStyle), "MyNodeStyle", 1);

Visual Basic  Copy Code

Diagram.RegisterClass(GetType(MyNode), "MyNode", 1)
Diagram.RegisterClass(GetType(MyNodeStyle), "MyNodeStyle", 1)

Now you can style and theme your custom nodes. Here is a theme, which affects the MyBrush property of all MyNode items in a diagram:

C#  Copy Code

Theme theme = new Theme();
MyNodeStyle myNodeStyle = new MyNodeStyle();
myNodeStyle.MyBrush = new SolidBrush(Colors.PaleGoldenrod);
theme.RegisterStyle(typeof(MyNode), myNodeStyle);
diagram.Theme = theme;

Visual Basic  Copy Code

Dim theme As New Theme()
Dim myNodeStyle As New MyNodeStyle()
myNodeStyle.MyBrush = New SolidBrush(Colors.PaleGoldenrod)
theme.RegisterStyle(GetType(MyNode), myNodeStyle)
diagram.Theme = theme

It is important to remember that there are no global default values for custom properties. Therefore you should be prepare to handle null values from GetValue or ensure that at least one of the five steps in the precedence list above produces a value.