WPF Diagrams 2.0 – Custom node styles

WPF Diagrams 2.0 gives you the full power of WPF to customize any part of a diagram. Nodes, connections, connection points, user interface controls, the background grid and the toolbox can all be styled to fit the unique requirements of you applications. In today’s blog post we take a look at how to customize the appearance of a diagram node. Back in WPF Diagrams 1.0, this process was split into 3 parts: a template selector for defining the shape of the node, a style selector for overriding the user control styles, and a calculator selector for customizing the positions of the connection points. In WPF Diagrams 2.0, all these things are conveniently merged together so you can maintain all the styling code for a single node in one place. Here we will just be looking at defining the look of the node itself.

Creating a node style

To customize a node, start off by creating a WPF style that has a target type of DiagramNodeElement. To define the look of the node, use a setter to access the NodeTemplate property which will be a DataTemplate. Here you can include any UI elements such as borders, paths and layout panels to customize the nodes appearence. This is also where you can place a content presenter to host the nodes’ data. Here is an example of a custom decision node style for a flow diagram:

<LinearGradientBrush x:Key="DecisionNodeBorder" StartPoint="0,0" EndPoint="0,1">
    <GradientStop Color="Yellow" Offset="0" />
    <GradientStop Color="Goldenrod" Offset="0.8" />
</LinearGradientBrush>
 
<LinearGradientBrush x:Key="DecisionNodeBackground" StartPoint="0,0" EndPoint="0,1">
    <GradientStop Color="Goldenrod" Offset="0" />
    <GradientStop Color="Yellow" Offset="0.8" />
</LinearGradientBrush>
 
<Style x:Key="DecisionNodeStyle" TargetType="ms:DiagramNodeElement">
    <Setter Property="FontWeight" Value="SemiBold" />
    <Setter Property="NodeTemplate">
        <Setter.Value>
            <DataTemplate>
                <Grid>
                    <Path IsHitTestVisible="false"
                              ms:DiagramNodeElement.IsGeometryProvider="True"
                              Data="M 0.5 0 L 1 0.5 L 0.5 1 L 0 0.5 Z" Stretch="Fill"
                              Fill="{StaticResource DecisionNodeBackground}"
                              StrokeThickness="5"
                              Stroke="{StaticResource DecisionNodeBorder}" />
                    <ContentPresenter Content="{Binding}" ContentTemplateSelector="{Binding NodeContentTemplateSelector, RelativeSource={RelativeSource AncestorType={x:Type ms:DiagramNodeElement}}}" />
                </Grid>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

This style creates a simple diamond shape with a thick border and yellow brushes. The shape itself is created using the path object seen inside the data template. By setting the DiagramNodeElement.IsGeometryProvider attached property to true, the path geometry will be used as the mouse hit testing area for this node. The IsHitTestVisible property has been set to false so that the path does not cover the move thumb UI. The content presenter is for displaying the nodes’ data. This has been set up to automatically use the default content template, or a custom template if one was provided.

Customizing a ShapeNode

WPF Diagrams 2.0 includes a node class called ShapeNode. This can be used to represent lots of nodes that are only different because of their shape. This node provides support for automatically creating its own tool box visuals and data template. This means that when you need to customize a ShapeNode, all you need to do is specify the style of the shape path rather than the whole data template. The StepNode of a flow diagram inherits from ShapeNode to represent all sorts of different steps. Here is example code for customizing a flow diagram StepNode:

<LinearGradientBrush x:Key="StepNodeBackground" StartPoint="0,0" EndPoint="0,1">
    <GradientStop Color="Gray" Offset="0" />
    <GradientStop Color="LightGray" Offset="0.8" />
</LinearGradientBrush>
 
<LinearGradientBrush x:Key="StepNodeBorder" StartPoint="0,0" EndPoint="0,1">
    <GradientStop Color="LightGray" Offset="0" />
    <GradientStop Color="Gray" Offset="0.5" />
</LinearGradientBrush>
 
<Style x:Key="StepNodePathStyle" TargetType="Path">
    <Setter Property="Fill" Value="{StaticResource StepNodeBackground}" />
    <Setter Property="StrokeThickness" Value="5" />
    <Setter Property="Stroke" Value="{StaticResource StepNodeBorder}" />
    <Setter Property="StrokeLineJoin" Value="Round" />
</Style>
 
<Style x:Key="StepNodeStyle" TargetType="ms:DiagramNodeElement">
    <Setter Property="FontWeight" Value="SemiBold" />
    <Setter Property="ms:ShapeTool.ShapePathStyle" Value="{StaticResource StepNodePathStyle}" />
</Style>

Here you can see that the StepNodePathStyle defines the colors and stroke thickness for the shape. The ShapeTool.ShapePathStyle attached property will allow the path style to be used when the node is displayed.

How to use a node style in a diagram

In order for the diagram control to use these custom node styles, you need to create a node style selector that maps different types of nodes to the styles you want them to use. This node style selector can then be used to set the NodeStyleSelector property of the diagram formatter used by the diagram control. Here is an example of a style selector for a flow diagram that uses the styles seen above along with a couple of others:

<ms:ShapeNodeStyleSelector x:Key="NodeStyleSelector">
    <ms:TypeStyle DataType="ms:StepNode" Style="{StaticResource StepNodeStyle}" />
    <ms:TypeStyle DataType="ms:StartNode" Style="{StaticResource StartNodeStyle}" />
    <ms:TypeStyle DataType="ms:EndNode" Style="{StaticResource EndNodeStyle}" />
    <ms:TypeStyle DataType="ms:DecisionNode" Style="{StaticResource DecisionNodeStyle}" />
</ms:ShapeNodeStyleSelector>

And here is the result:

Custom node style

The code examples I have used in this blog post come from the CustomStyle.FlowDiagrams sample seen in the samples solution. This sample demonstrates how to customize nodes and connections. You can find all the node styles in the DemoStyleNodes.xaml file, and the diagram formatter is set up in the DemoStyles.xaml file. If you have any questions about how to customize any part of a diagram, then let us know by leaving a comment on this blog post, or stop by our forums.

Tagged as WPF Diagrams

One Response to “WPF Diagrams 2.0 – Custom node styles”

  • Creating custom node styles for WPF Diagrams…

    Thank you for submitting this cool story – Trackback from DotNetShoutout…

  • Leave a Reply

Archives

Join our mailer

You should join our newsletter! Sent monthly:

Back to Top