Home » Blog

rounded header

Archive for the ‘WPF Diagrams’ category

Nightly news, 21 October 2011

So, last week Web Workbench, this week NHibernate Designer… will next week be WPF Elements 5? Stay tuned! In the meantime, here’s what else we’ve delivered this week.

WPF Elements

  • Added support for automatic ranges on alternate Y axes
  • Fix for a design-time issue with the RadialGauge control
  • Added limited control over data sampling
  • Fixed a bug where tooltips could not be applied to line series
  • Initial support for tick marks on the RadialGauge control

LightSpeed

  • Enhancements to native projection support

WPF Diagrams

  • Added option to include connections in marquee selects

Web Workbench

  • Better handling of Unix-style line endings
  • Fixed spurious squiggly on CSS escape syntax
  • Fix for non-Latin literals in CoffeeScript

You can download the updates right now — free editions from the downloads page, full editions from the store. (Web Workbench auto-updates through the Visual Studio gallery.)

Nightly news, 7 October 2011

Machine rebuild time here at Mindscape HQ, and very disappointed to learn that JD did not christen the rebuilt box “Mungo the Computational.” But he did go to the trouble of giving me a Steve Bell penguin for my user image, so all is forgiven. Fortunately, in between relaxing in front of the Windows 7 setup screen, we’ve also shipped a bunch of updates in the latest nightly builds. Here’s what’s new this week.

LightSpeed

  • Some fixes around ordering across associations
  • Added support for calculation/aggregation operators over subqueries
  • Improvements to the LINQ Count() operator over projection subqueries
  • The designer defaults policy can now override the defaults for generating DataMember attributes on associations
  • Fix for associations not respecting DependentAttribute if the foreign key was a string
  • Fix for value objects in derived entities not being materialised if using FindBySql or a stored procedure, and the inheritance model was class table inheritance, and the query was through the base class

WPF Diagrams

  • Added hooks for customising marquee selection behaviour

WPF Elements

  • Automatic label step calculation for Y axes

Phone Elements

  • Landscape support for the palette colour picker

NHibernate Designer

  • Option to suppress association properties in generated code

Nightly builds of free products are available on the Downloads page; for retail editions you can get them from the store.

Nightly news, 9 September 2011

Big anticipation here at the Mindscape office as our new Kinect accidentally falls out of its box, at the same time as the Kinect SDK accidentally installs itself onto Jason’s computer. They say accidents come in threes, so we are just waiting for Jason to accidentally write a bunch of cool Kinect programs. Stay tuned!

In the meantime, some rather more mundane developments in the latest nightly builds…

LightSpeed

  • New Show Data command for, well, showing your data
  • Fixes for certain CTI join scenarios

NHibernate Designer

  • We now support per-project code generation templates for you hacker types

WPF Diagrams

  • Added new hit testing methods, and fixed a bug in the FindElementAtPoint method

WPF Elements

  • UI zooming and panning support for alternate Y axes

Silverlight Elements

  • UI zooming and panning support for alternate Y axes

All these updates are available in the current nightly builds — free editions from the downloads page, full editions from the store.

Nightly news, 2 September 2011

Two weeks of nightly updates to catch up on today, thanks to TechEd, so let’s get stuck in. Here’s what you’ll find in the latest hot builds.

WPF Diagrams

  • DiagramToolBox support for scroll bar visibility attached properties
  • Node tool drag sizing is now cancelled if the user doesn’t click on the diagram surface
  • You can now control the heuristic function used by the A* pathfinder
  • New sample: custom shapes
  • Added an IsDragResizeEnabled property for enabling or disabling drag-sizing when using a charged cursor to create new node

LightSpeed

  • Fix for a spurious discriminator warning if a STI root class derived from another class using concrete table inheritance
  • We’ve relaxed the warnings for discriminators on abstract classes
  • Improved error if you set an entity to be its own direct parent. “Doctor, it hurts when I do this.”
  • If you drag from Server Explorer and you haven’t saved your password, we’ll now try to detect this and remind you
  • Fix for error in certain grouping queries with joins
  • Email validator now accepts the ‘+’ character in addresses
  • Improvements to find by identifier in DistributedUnitOfWork

Phone Elements

  • Support for styling alternate Y axes

WPF Elements

  • Fixed a property grid bug with keyboard navigation on expanded nodes

Web Workbench

  • Fixed a couple more cases where we were indicating syntax errors on correct CSS

Free editions of the nightly builds are on the downloads page, and full editions are in the store.

WPF Diagrams: Custom Diagram Shapes

tag icon Tagged as WPF Diagrams

When creating a diagramming application, you may find that lots of different nodes in your diagram are only distinguished by their shape and number of connection points, but they all have the same connection validation and functionality. WPF Diagrams 2.0 provides a type of node called “ShapeNode” which is perfect for these scenarios. Different instances of ShapeNode can have completely different shapes and connection point setups. WPF Diagrams 2.0 includes more than 70 predefined shapes to get you started. You can of course extend the ShapeNode class if you need to provide additional functionality and properties specific to the needs of your applications — but if all you want is a new shape, then the built-in ShapeNode class will do fine.

In this blog post I will show you how to define your own shapes that can be used by a ShapeNode. Defining a custom shape takes very little code, and the diagramming foundation will then automatically create the toolbox icons, cursor visuals and node templates all for you. Here is a preview of what we will be creating:

Custom diagram shapes

Getting started

If you don’t already have a diagramming application that you can start adding custom shapes to, then start by reading this ‘getting started’ blog post.

Defining a custom shape is made up of 2 parts: a DiagramShape, and a ShapeLayout. The DiagramShape contains the logical information such as the number of connection points on each side and its display name. This is written in a C# file. The ShapeLayout provides the graphical information including the path geometries, connection point positions and path styles. This is written in a XAML resource dictionary. For all the custom shapes described in this blog post, I have put the DiagramShape definitions in a static class called CustomShapes, and the ShapeLayout definitions are in a resource dictionary in MainWindow.xaml.

Defining a simple shape

To start off, we will define a very simple shape made up of a single path. The DiagramShape code for this looks like the following:

public static class CustomShapes {
  public static readonly DiagramShape Link = new DiagramShape("Link");
}

As you can see it is very simple. The string passed into the DiagramShape constructor is the name of the shape and is used for serialization. By default this is also used as the display name, but you can also specify the display name by setting the DisplayName property. Display names are displayed in the tooltip of the node tool in the tool box. This custom shape also doesn’t specify the number of connection points. By default, there will be one connection point on the left, top, right and bottom sides of the shape.

Next we need to write the ShapeLayout to define the graphical parts of the shape. Here is an example:

<ms:ShapeLayout x:Key="{x:Static local:CustomShapes.Link}"
                Geometry="M 0 0 L 0.8 0 L 0.8 0.3 L 1 0.3 L 1 0.7 L 0.8 0.7 L 0.8 1 L 0 1 L 0 0.7 L 0.2 0.7 L 0.2 0.3 L 0 0.3 Z"
                ConnectionPointPositions="L 0.2,0.5"
                ContentMargin="2*,*,*,*"
                />

The first thing to notice is that the DiagramShape object we created is being used as the resource key for the ShapeLayout. This is how WPF Diagrams matches up shape layouts to shape declarations.

The geometry for the shape itself is defined by the Geometry property, in this case using the PathGeometry mini-language. Note that all the values used in the path geometry are between 0 and 1. This makes it easier to scale the shape to any size. I have also customized the connection point positions and content margin which are topics outside the scope of this blog post (see the docs for more info).

The only thing left to do now is include this custom shape in the tool box. The diagramming foundation then automatically creates the tool box icon, cursor visual, diagram node template and applies the default styles to match all the built in shapes. Adding the custom shape to the tool box is done by adding the following line of code to a DiagramToolBoxGroup:

<ms:DiagramNodeTool ms:ShapeTool.Shape="{x:Static local:CustomShapes.Link}" />

The value of the ShapeTool.Shape attached property again just needs to be the DiagramShape object itself — the diagramming foundation will take it from there.

Defining a shape with multiple paths

Sometimes a single path geometry just isn’t going to do it. You may want to define shapes that are made up of multiple paths, each which may have different colors or styles. Fortunately the ShapeLayout class can support this too. Rather than setting the Geometry property, you can populate the Paths collection. The nuclear symbol seen in the image above has been achieved with this approach. The DiagramShape definition for this is the same as the previous shape but has a different name. The ShapeLayout is displayed below:

<ms:ShapeLayout x:Key="{x:Static local:CustomShapes.Nuke}">
  <ms:ShapeLayout.Paths>
    <Path Fill="Black" Data="M 0.5 0 A 0.5 0.5 180 0 1 0.5 1 A 0.5 0.5 180 0 1 0.5 0 Z"
          Stretch="Fill"
          ms:DiagramNodeElement.IsGeometryProvider="True" />
    <Path Fill="#FFD60F" Data="M 0 0 L 0.5 0.071 A 0.429 0.429 180 0 1 0.5 0.929 A 0.429 0.429 180 0 1 0.5 0.071 L 1 1 L 0.5 0.071 Z"
          Stretch="Fill" />
    <Path Fill="Black" Data="M 0 0 L 0.129 0.507 A 0.327 0.327 60 0 1 0.311 0.191 L 0.436 0.409 A 0.118 0.118 60 0 0 0.382 0.507 L 0.129 0.507 L 1 1 L 0.129 0.507 Z"
          Stretch="Fill" />
    <Path Fill="Black" Data="M 0 0 L 0.684 0.191 A 0.327 0.327 60 0 1 0.867 0.507 L 0.617 0.507 A 0.118 0.118 60 0 0 0.56 0.409 L 0.684 0.191 L 1 1 L 0.684 0.191 Z"
          Stretch="Fill" />
    <Path Fill="Black" Data="M 0 0 L 0.68 0.822 A 0.327 0.327 60 0 1 0.32 0.822 L 0.444 0.609 A 0.118 0.118 60 0 0 0.555 0.609 L 0.68 0.822 L 1 1 L 0.68 0.822 Z"
          Stretch="Fill" />
    <Path Fill="Black" Data="M 0 0 L 0.5 0.444 A 0.056 0.056 180 0 1 0.5 0.556 A 0.056 0.056 180 0 1 0.5 0.444 L 1 1 L 0.5 0.444 Z"
          Stretch="Fill" />
  </ms:ShapeLayout.Paths>
</ms:ShapeLayout>

One thing to note here is the attached property being set on the first path. This attached property defines which path should be used as the hit testing area for the shape. The first path in the nuclear symbol is simply the outer circle. If you do not set this attached property, then the bounding box of the shape will be used as the hit testing area by default.

Flexible styling

In a few scenarios, you may find you want to have different path styles applied to the tool box icon, cursor visual and node template for the same shape. The lightning bolt shape seen in the image above has a blue tool box icon, a semi-transparent cursor visual, and a yellow node template. This can be achieved by using attached properties on a Path object as seen here:

<ms:ShapeLayout x:Key="{x:Static local:CustomShapes.LightningBolt}"
                ConnectionPointPositions="L 0.255,0.453; 0.481,0.689 T 0,0.198; 0.396,0 R 0.604,0.292; 0.764,0.557 B 1,1">
  <ms:ShapeLayout.Paths>
    <Path Data="M 0 0.198 L 0.396 0 L 0.604 0.292 L 0.519 0.321 L 0.764 0.557 L 0.689 0.594 L 1 1 L 0.481 0.689 L 0.557 0.642 L 0.255 0.453 L 0.358 0.396 Z"
          Stretch="Fill" StrokeLineJoin="Round"
          ms:ShapeLayout.ToolboxIconStyle="{StaticResource LightningToolBoxStyle}"
          ms:ShapeLayout.CursorVisualStyle="{StaticResource LightningCursorVisualStyle}"
          ms:ShapeLayout.NodeStyle="{StaticResource LightningNodeStyle}"
          ms:DiagramNodeElement.IsGeometryProvider="True" />
  </ms:ShapeLayout.Paths>
</ms:ShapeLayout>

Each attached property is setting a path style to be used in either the tool box, cursor visual or node template.

A full sample demonstrating all of these concepts can be downloaded here. To run the sample, make sure to include a reference to your copy of the WPF Diagrams Foundation DLL.

The WPF Diagrams documentation includes more info about creating custom shapes, including how to serialise and deserialise diagrams that use custom shapes. See Help Topics > Creating Your Own Shapes in the online docs or the help file.

If you have any further questions about implementing custom diagram shapes then we would love to hear from you. Either leave a comment on this blog post, or stop by our forum.

Data Products Visual Controls Community Store
LightSpeed ORM
NHibernate Designer
SimpleDB Tools
SharePoint Tools
WPF Elements
WPF Diagrams
Silverlight Elements
Forums
Blog
Register
Login
Subscribe to newsletter
Buy Now
My Account
Volume Discounts
Purchase Orders
Contact Us