Back to Devexpress

How to: Create Custom Shapes with Connection Points Using XAML

windowsforms-118076-controls-and-libraries-diagrams-examples-how-to-create-custom-shapes-with-connection-points-using-xaml.md

latest10.8 KB
Original Source

How to: Create Custom Shapes with Connection Points Using XAML

  • Nov 13, 2018
  • 5 minutes to read

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:

csharp
static void RegisterPackUriScheme() {
    new FlowDocument();
}
vb
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.

View Example

xaml
<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>
csharp
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);
        }
    }

}
csharp
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();
        }
    }
}
csharp
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;
        }
    }
}
vb
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
vb
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
vb
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