windowsforms-118076-controls-and-libraries-diagrams-examples-how-to-create-custom-shapes-with-connection-points-using-xaml.md
This example demonstrates how to describe custom shapes using the XAML markup instead of XML.
Note
The PresentationCore library used in this example affects the DPI awareness of WinForms applications (see T346466 - DiagramControl disables DPI scaling for the entire application). Use this approach only if your application is not DPI aware or the PresentationCore library is pre-loaded in the Program.Main method as follows:
static void RegisterPackUriScheme() {
new FlowDocument();
}
Private Shared Sub RegisterPackUriScheme()
Dim TempFlowDocument As FlowDocument = New FlowDocument()
End Sub
In other cases, it is preferred to describe shapes using XML, as demonstrated in the following example: How to: Create Custom Shapes with Connection Points.
<p:ResourceDictionary xmlns:p="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns="http://schemas.devexpress.com/winfx/2008/xaml/diagram"
xmlns:local="clr-namespace:XtraDiagram.CreateCustomShapes">
<ShapeTemplate x:Key="{local:ShapeKey Shape1}" DefaultSize="50, 100" >
<Start X="0" Y="0"/>
<Line X="1" Y="0" />
<Line X="0.8" Y="0.8" />
<Line X="0" Y="1" />
<ShapeTemplate.ConnectionPoints>
<ShapePoint X="0" Y="0" />
<ShapePoint X="0.5" Y="0" />
<ShapePoint X="1" Y="0" />
<ShapePoint X="0.8" Y="0.8" />
<ShapePoint X="0" Y="1" />
<ShapePoint X="0" Y="0.5" />
</ShapeTemplate.ConnectionPoints>
</ShapeTemplate>
<!--W - shape width-->
<!--H - shape height-->
<ShapeTemplate x:Key="{local:ShapeKey Shape2}" DefaultSize="60, 120">
<Start X="0" Y="0" FillColor="Brown"/>
<Arc X="1" Y="0" Size="CreateSize(W/2, H/10)" Direction="Counterclockwise" />
<Arc X="1" Y="1" Size="CreateSize(W/10, H/2)" Direction="Counterclockwise" />
<Arc X="0" Y="1" Size="CreateSize(W/2, H/10)" Direction="Counterclockwise" />
<Arc X="0" Y="0" Size="CreateSize(W/10, H/2)" Direction="Counterclockwise" />
<ShapeTemplate.ConnectionPoints>
<ShapePoint X="0" Y="0" />
<ShapePoint X="1" Y="0" />
<ShapePoint X="0" Y="1" />
</ShapeTemplate.ConnectionPoints>
</ShapeTemplate>
<!--P0 - parameter 0-->
<!--P in Point definition - parameter value -->
<!--P in Value definition - parameter point-->
<ShapeTemplate x:Key="{local:ShapeKey Shape3}" DefaultSize="60, 120">
<Start X="0" Y="0" FillColor="Brown"/>
<Arc X="1" Y="0" Size="CreateSize(W/2, P0 * H)" Direction="Counterclockwise" />
<Line X="1" Y="1"/>
<Line X="0" Y="1"/>
<Line X="0" Y="0"/>
<ShapeTemplate.ConnectionPoints>
<ShapePoint X="0" Y="0" />
<ShapePoint X="1" Y="0" />
<ShapePoint X="0" Y="1" />
</ShapeTemplate.ConnectionPoints>
<ShapeTemplate.Parameters>
<Parameter DefaultValue="0.1"
Point="CreatePoint(W / 2, P * H)"
Value="P.Y / H"
Min="0" Max="1" />
</ShapeTemplate.Parameters>
</ShapeTemplate>
<!--this shape contains two rows-->
<ShapeTemplate x:Key="{local:ShapeKey Shape4}" DefaultSize="60, 120" Rows="H*P0;H*(1-P0)" IsQuick="True">
<Start X="0" Y="0" FillColor="Green"/>
<Line X="1" Y="0"/>
<Line X="1" Y="1"/>
<Line X="0" Y="1"/>
<Start X="0" Y="1" FillColor="Red"/>
<Line X="1" Y="1"/>
<Line X="1" Y="2"/>
<Line X="0" Y="2"/>
<ShapeTemplate.ConnectionPoints>
<ShapePoint X="0.5" Y="0" />
<ShapePoint X="1" Y="1" />
<ShapePoint X="0.5" Y="2" />
<ShapePoint X="0" Y="1" />
</ShapeTemplate.ConnectionPoints>
<ShapeTemplate.Parameters>
<Parameter DefaultValue="0.5"
Point="CreatePoint(W, P * H)"
Value="P.Y / H"
Min="0" Max="1" />
</ShapeTemplate.Parameters>
</ShapeTemplate>
</p:ResourceDictionary>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DevExpress.Diagram.Core;
using DevExpress.Diagram.Core.Shapes;
using System.Windows;
namespace XtraDiagram.CreateCustomShapes {
public partial class Form1 : DevExpress.XtraBars.Ribbon.RibbonForm {
public Form1() {
InitializeComponent();
RegisterCustomShapes();
this.diagramControl1.SelectedStencils = new StencilCollection(new string[] { "CustomShapes" });
}
protected override void OnLoad(EventArgs e) {
base.OnLoad(e);
this.diagramControl1.InitializeRibbon(this.ribbonControl1);
}
void RegisterCustomShapes() {
var shapesDictionary = new ResourceDictionary() {
Source = new Uri("DiagramResources.xaml", UriKind.RelativeOrAbsolute)
};
var stencil = DiagramStencil.Create("CustomShapes", "Custom Shapes", shapesDictionary, shapeName => shapeName);
DiagramToolboxRegistrator.RegisterStencil(stencil);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Documents;
using System.Windows.Forms;
namespace XtraDiagram.CreateCustomShapes {
static class Program {
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main() {
RegisterPackUriScheme();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
static void RegisterPackUriScheme() {
new FlowDocument();
}
}
}
using System;
using System.Linq;
using System.Windows;
using DevExpress.Diagram.Core;
namespace XtraDiagram.CreateCustomShapes {
public class ShapeKey : ResourceKey, IOrderedKey {
[ThreadStatic]
static int idCore;
readonly int id;
readonly string resourceKey;
public int Id { get { return id; } }
public string ResourceKey { get { return resourceKey; } }
public override System.Reflection.Assembly Assembly {
get { return null; }
}
public ShapeKey(string resourceKey) {
this.id = idCore++;
this.resourceKey = resourceKey;
}
}
}
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Linq
Imports System.Text
Imports System.Windows.Forms
Imports DevExpress.Diagram.Core
Imports DevExpress.Diagram.Core.Shapes
Imports System.Windows
Namespace XtraDiagram.CreateCustomShapes
Partial Public Class Form1
Inherits DevExpress.XtraBars.Ribbon.RibbonForm
Public Sub New()
InitializeComponent()
RegisterCustomShapes()
Me.diagramControl1.SelectedStencils = New StencilCollection(New String() { "CustomShapes" })
End Sub
Protected Overrides Sub OnLoad(ByVal e As EventArgs)
MyBase.OnLoad(e)
Me.diagramControl1.InitializeRibbon(Me.ribbonControl1)
End Sub
Private Sub RegisterCustomShapes()
Dim shapesDictionary = New ResourceDictionary() With {.Source = New Uri("DiagramResources.xaml", UriKind.RelativeOrAbsolute)}
Dim stencil = DiagramStencil.Create("CustomShapes", "Custom Shapes", shapesDictionary, Function(shapeName) shapeName)
DiagramToolboxRegistrator.RegisterStencil(stencil)
End Sub
End Class
End Namespace
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Windows.Documents
Imports System.Windows.Forms
Namespace XtraDiagram.CreateCustomShapes
Friend NotInheritable Class Program
Private Sub New()
End Sub
''' <summary>
''' The main entry point for the application.
''' </summary>
<STAThread> _
Shared Sub Main()
RegisterPackUriScheme()
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
Application.Run(New Form1())
End Sub
Private Shared Sub RegisterPackUriScheme()
Dim TempFlowDocument As FlowDocument = New FlowDocument()
End Sub
End Class
End Namespace
Imports System
Imports System.Linq
Imports System.Windows
Imports DevExpress.Diagram.Core
Namespace XtraDiagram.CreateCustomShapes
Public Class ShapeKey
Inherits ResourceKey
Implements IOrderedKey
<ThreadStatic> _
Private Shared idCore As Integer
Private ReadOnly id_Renamed As Integer
Private ReadOnly resourceKey_Renamed As String
Public Overrides ReadOnly Property Assembly() As System.Reflection.Assembly
Get
Return Nothing
End Get
End Property
Private ReadOnly Property IOrderedKey_Id As Integer Implements IOrderedKey.Id
Get
Return id_Renamed
End Get
End Property
Private ReadOnly Property IOrderedKey_ResourceKey As String Implements IOrderedKey.ResourceKey
Get
Return resourceKey_Renamed
End Get
End Property
Public Sub New(ByVal resourceKey As String)
Me.id_Renamed = idCore
idCore += 1
Me.resourceKey_Renamed = resourceKey
End Sub
End Class
End Namespace