A node can have any number of independent logical and physical connector elements, known as "ports". Just set the go:Node.PortId attached property on any FrameworkElement.

This sample demonstrates how a node could have a variable number of ports, along with the ability to add or remove ports dynamically. The node data class, Unit, has four lists of data, one for each side of the node. Each of these data, Socket, describes one port. The Socket.Name is used as the Node.PortId, the Socket.Color is used to customize the color of the port element, and the Side and Index properties remember where the port should be.

The NodeTemplate uses four ListBoxes around a central Rectangle. The ListBox.ItemsSource is data-bound to a list of Unit Sockets. The ListBox.ItemTemplate is basically a Rectangle, binding the go:Node.PortId to the Socket.Name unique string.

Because a ListBox normally supports selecting items, we use a custom InertListBox and InertListBoxItem in order to disable mouse event handling.

There are four Buttons to add a port on the selected node. These buttons are enabled by whether Diagram.SelectedNode is non-null. Each button, when clicked, adds a Socket to one side of the selected Unit. Through the magic of data-binding, that will cause the corresponding ListBox to get an additional FrameworkElement representing a port. Note how this change is performed within a transaction, as should every change to a model or its data.

A particular port can be removed by right-clicking on it. (Except in Silverlight 3, where right mouse clicks are not supported.)