Search
Components and XML

As described in the Using Components topic, to use components in MindFusion.Diagramming you need to instantiate them and add them to the Components collection of a CompositeNode. MindFusion.Diagramming provides a more convenient method for defining component hierarchies - through XML.

Definition

Each node in the source XML represents a component or an object. The child nodes in the XML represent child components. The XML attributes represent either property assignments or event handler attachments. A simple component hierarchy defined in XML is illustrated below:

XML  Copy Code

<SimplePanel>

  <Shape Name="Shape" Shape="Rectangle" />

  <Border Padding="2">
    <GridPanel>
      <GridPanel.Columns>
        <GridColumn Width="30" />
        <GridColumn />
      </GridPanel.Columns>
      <GridPanel.Rows>
        <GridRow />
      </GridPanel.Rows>

      <Image Name="Image" ImageAlign="Fit" />

      <StackPanel Orientation="Vertical" GridColumn="1">
        <Text Name="Title" Font="Arial, 12pt, style=Bold" TextAlignment="Near" />
        <Text Name="FullName" TextColor="Blue" TextAlignment="Near" />
        <Text Name="Text" Font="Arial, 8pt" TextAlignment="Near" />
      </StackPanel>
    </GridPanel>
  </Border>

</SimplePanel>

Because the XML documents have a single root, the component hierarchies defined through XML can have a single root too. In the case when a hierarchy needs to have more than one root each root can be defined in its own XML or all the root components can be grouped under a single component container.

As is observed in the sample above the components can be specified through shortcut names. The following table lists all available shortcuts:

Component

Shortcut Name

BorderComponent

Border

ButtonComponent

Button

CheckBoxComponent

CheckBox

EditComponent

Edit

ImageComponent

Image

ShapeComponent

Shape

TextComponent

Text

NumericEditComponent

NumericEdit

SliderComponent

Slider

SpinnerComponent

Spinner

The components can also be defined using their full names.

Composite Properties

Some properties have too complex values and cannot be represented with attributes. Consider for example the collection properties, such as the Columns and Rows properties of the GridPanel. These properties can be defined as child nodes using the specialized syntax illustrated below:

XML  Copy Code

<ComponentName>
  <ComponentName.PropertyName>
    <PropertyValue />
  </ComponentName.PropertyName>
</Component>

For example, to define Content of a ButtonComponent, you can use the following syntax:

XML  Copy Code

<Button>
  <Button.Content>
    <Text Text="Hello world!" />
  </Button.Content>
</Button>

Images

Images can be defined in XML using Bitmap objects and string paths. Here is an example:

XML  Copy Code

<Image>
  <Image.Image>
    <Bitmap>Images/MyImage.png</Bitmap>
  </Image.Image>
</Image>

In the example above "Images/MyImage.png" will be interpreted as a string and the loader will attempt to create a new Bitmap instance by passing this string as an argument to the Bitmap(string) constructor.

Shapes

The Shape of shape components can be defined in XML by either specifying the name of a predefined shape or by using the specialized syntax for graphical paths. The example below defines two ShapeComponent instances in a StackPanel. The first shape component uses the predefined Ellipse shape and the second uses a custom arrow shape:

XML  Copy Code

<StackPanel Spacing="1">
  <Shape Shape="Ellipse" Width="6" Height="6" Pen="Red" Brush="Yellow" />
  <Shape Shape="M0,30 L50,30 L50,0 L100,50 L50,100 L50,70 L0,70 z" Width="6" Height="6" Pen="Green" Brush="LimeGreen" />
</StackPanel>

The specialized graphical path syntax supports the following subset of operations:

Command

Description

MX,Y

Moves to point (X, Y).

LX,Y

Draws a line from the current point to point (X, Y).

CX1,Y1 X2,Y2 X3,Y3

Draws a curve from the current point to (X3, Y3) using points (X1, Y1) and (X2, Y2) as control points.

AW,H R A D X,Y

Draws an arc with size (W, H) using rotation R and an end point (X, Y). A specifies whether to draw the large arc (1 - large arc, 0 - small arc) and D specifies direction - (1 - positive angle, 0 - negative).

z

Closes the figure.

Event Handlers

Event handlers can be specified using attributes by setting the name of the event as the name of the attribute and the name of the handling method as attribute value. Consider the following example:

XML  Copy Code

<Button Clicked="OnButtonClicked" />

To be able to attach event handlers, the loader needs additional information. See Handling Events below.

Loading XML

Component hierarchies defined in XML can be loaded using the XmlLoader class. The class provides several static Load method overloads for loading XML from different sources - string, Stream or XmlDocument. Each of the Load methods returns a ComponentBase representing the root of the loaded hierarchy. This component can then be added to a CompositeNode or as a child of another component. The following example illustrates how to use the XmlLoader:

C#  Copy Code

CompositeNode node = new CompositeNode();
node.Components.Add(XmlLoader.Load(@"<Edit Text=""Some text"" />"));

Handling Events

If the source XML contains definitions of event handlers you need to use one of the Load overloads, which accepts an event handler target as argument. If an event handler definition is encountered and no target is specified the loader will throw an exception. Consider the following XML:

XML  Copy Code

<Button Clicked="OnButtonClicked" />

In order to successfully load this XML, the Load(string, object) overload should be invoked passing as second argument an object, which defines an OnButtonClicked method with matching prototype.

Resolving Types

The XmlLoader is capable of resolving external (non-component) types found in the source XML by performing a complete search of all currently loaded assemblies. However, this can be slow in certain scenarios. In addition certain types might not resolve properly because the loader always uses the first type that matches the specified name regardless of namespace. Luckily the XmlLoader provides means to manually resolve external types. In order to take advantage of this, you have to implement the ITypeResolver interface and pass an instance of your class to the corresponding Load overload. For any external type found, the loader will invoke the ResolveType method. If the method returns null (Nothing in Visual Basic) the loader will attempt to resolve the type using its default logic.

Error Handling

It is not unusual for the XmlLoader to throw an exception when loading components from XML. There are many reasons for this to happen, including ill-formatted XML. Therefore it is recommended to always try and catch exceptions when loading components from XML.