Home       Products       Support       Forums       FREE Trial Download       Customers       Project Gallery       About Us       Contact Us       Ordering Info   

 

"We found the GoDiagram tools to be extremely powerful, flexible, and easy to use."
Joey Runyans
Senior Software Engineer
Aegis Technologies Group



       
 
GoXam - Data Binding, Models and Data Templates
 
View Cart
 

GoXam is the first diagram control to be designed from the ground up to be a natural extension of the Microsoft XAML language used in Windows Presentation Foundation (WPF) and Silverlight. Essential to this environment are Data Binding and Data Templates. GoXam integrates these concepts cleanly and coherently into a powerful diagramming extension to XAML.

Diagram Models and Data Binding

One of the principal features of XAML-defined presentation is the use of data binding. A diagram control, however, must support more complex features than the typical control.

There are at least two kinds of relationships that a diagram can support between data items:

  • Relationships forming a graph of nodes and links (or in similar terminology: nodes and arcs, or entities and relationships, or vertices and edges)
  • Grouping relationships, where a group contains members; perhaps for part/sub-part containment, or for the nesting of subgraphs

GoXam makes use of a model to discover, maintain, navigate, and modify these relationships based on the data to which the diagram is bound. Not all data behind graphs has the same complexity, so we provide three primary model classes to give you the right blend of ease of use, performance and power.

The TreeModel is the simplest model. It is suitable for applications where the data forms a graph that is a tree structure.

The GraphModel is used when each node has a list of nodes connecting to or from that node. The GraphModel also supports simple grouping.

The third model is the GraphLinksModel, where your data includes a source for nodes and also a source for the links that connect them. GraphLinksModel also supports link information that allows different link connection points on each node. It also supports labels on links.

Once a model is created, and the model's data is initialized and assigned to a Diagram, you have created an automatic link between the model and the diagram. Changes to the model update the diagram, and changes to the diagram (typically by the user) update the model.

If you look at our online Silverlight demos, you'll be amazed at how little code you need to write to visualize and update your data.

Data Templates for Nodes

The appearance of any node or link is determined not only by the data to which it is bound but also the DataTemplate used to define the elements of its visual tree. A data template is a reusable piece of XAML that defines how to display your bound data. So the appearance of your diagrams is separate from the code. Simply editing the XAML that defines a node or link can change a diagram's appearance.

Since nodes and links are defined by XAML, it is easy to incorporate all of the power of WPF and SIlverlight graphics (rectangles, text, paths, gradients, images, even video) into your diagrams, including the use of animation, storyboards and effects like Blur and Drop Shadow.

So, nodes can be simple
  using this NodeTemplate
simple GoXam diagram
 

  <DataTemplate>
    <TextBlock Text="{Binding Path=Data}" />
  </DataTemplate>

     
But it is also possible to define nodes that are as complex as your needs require (click to see XAML)
Click to Show DataTemplate XAML code
Click to Show DataTemplate XAML code
Click to Show DataTemplate XAML code
DataTemplate for Purple node Alpha:

<DataTemplate x:Key="NodeTemplate4">
  <!-- a NodePanel shows a background shape and places the other panel children inside the shape -->
  <go:NodePanel go:Node.SelectionAdorned="True"
                go:Node.ToSpot="LeftSide" go:Node.FromSpot="RightSide" >
    <!-- in Silverlight, use a Path instead of a go:NodeShape -->
    <go:NodeShape go:NodePanel.Figure="Database" Stroke="Black" StrokeThickness="1">
      <Shape.Fill>
        <!-- use a fancier brush than a simple solid color -->
        <LinearGradientBrush StartPoint="0.0 0.0" EndPoint="1.0 0.0">
          <LinearGradientBrush.GradientStops>
            <GradientStop Color="{Binding Path=Data.Color,
                    Converter
={StaticResource theStringColorConverter}}" Offset="0.0" />
            <GradientStop Color="White" Offset="0.5" />
            <GradientStop Color="{Binding Path=Data.Color,
                    Converter
={StaticResource theStringColorConverter}}" Offset="1.0" />
          </LinearGradientBrush.GradientStops>
        </LinearGradientBrush>
      </Shape.Fill>
    </go:NodeShape>
    <!-- this TextBlock element is arranged inside the NodePanel’s shape -->
    <TextBlock Text="{Binding Path=Data.Key}" TextAlignment="Center"
               HorizontalAlignment="Center" VerticalAlignment="Center" />
  </go:NodePanel>
</
DataTemplate>
DataTemplate for light blue OrgChart node:

    <DataTemplate x:Key="NodeTemplate" >
      <go:NodePanel go:Node.SelectionAdorned="True" >
        <Border Background="Azure" BorderBrush="Black" BorderThickness="1" MaxWidth="200" >
          <Grid MaxWidth="200">
            <Grid.RowDefinitions>
              <RowDefinition Height="Auto" />
              <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <Grid Grid.Row="0" >
              <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="Auto" />
              </Grid.ColumnDefinitions>
              <TextBlock Grid.Column="0" Text="{Binding Path=Data.Name}" FontWeight="Bold"
                         TextAlignment="Left" TextWrapping="Wrap" Margin="4 4 4 2" />
              <Border Grid.Column="1" BorderBrush="Black" BorderThickness="2"
                      Height="34" Margin="2"
                      Width="{Binding Path=Data.Flag,
                              Converter={StaticResource theImageSizeConverter}}">
                <Image Stretch="Fill" Source="{Binding Path=Data.Flag}" />
              </Border>
            </Grid>
            <TextBlock Grid.Row="1" Text="{Binding Path=Data.PersonData}"
                       TextAlignment="Left" TextWrapping="Wrap" Margin="4 4 4 2" />
          </Grid>
        </Border>
      </go:NodePanel>
    </DataTemplate>
DataTemplate for Entity Relationship node:

    <DataTemplate x:Key="NodeTemplate">
      <Border Background="Gray" BorderBrush="Gray" BorderThickness="2" CornerRadius="3"
              go:Part.SelectionAdorned="True" go:Part.Resizable="True"
              go:Node.FromSpot="AllSides" go:Node.ToSpot="AllSides"
              go:Node.Location="{Binding Path=Data.Location, Mode=TwoWay}">
        <Grid>
          <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
          </Grid.RowDefinitions>
          <Grid Grid.Row="0">
            <Grid.ColumnDefinitions>
              <ColumnDefinition Width="*" />
              <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="0" HorizontalAlignment="Center"
                       Text="{Binding Path=Data.Key}" FontWeight="Bold" />
            <Button Grid.Column="1" Content="*" Click="Button_Click" />
          </Grid>
          <ListView Grid.Row="1" Background="White" HorizontalAlignment="Stretch"
                    ItemsSource="{Binding Path=Data.Items}">
            <ListView.View>
              <GridView>
                <GridView.Columns>
                  <GridViewColumn>
                    <GridViewColumn.CellTemplate>
                      <DataTemplate>
                        <go:NodeShape
                            go:NodePanel.Figure="{Binding Path=Figure}"
                            Width="10" Height="10"
                            Fill="{Binding Path=Color,
                                   Converter={StaticResource theStringBrushConverter}}"
                            Stroke="Black" StrokeThickness="1" />
                      </DataTemplate>
                    </GridViewColumn.CellTemplate>
                  </GridViewColumn>
                  <GridViewColumn Header="Name"
                                  DisplayMemberBinding="{Binding Path=Name}" />
                </GridView.Columns>
              </GridView>
            </ListView.View>
          </ListView>
        </Grid>
      </Border>
    </DataTemplate>

Data Templates for Links

GoXam also supports DataTemplate for links, along with links features like Orthogonal, Bezier, rounded corners, jump overs and avoids-nodes routing. (click to see XAML)

Click to Show DataTemplate XAML code

Click to Show DataTemplate XAML code
Click to Show DataTemplate XAML code
Click to Show DataTemplate XAML code
Normal Routing
Orthogonal
with AvoidsNodes
Round Corners
DataTemplate for simple links with an arrowhead

<DataTemplate x:Key="LinkTemplate2">
  <go:LinkPanel go:Part.SelectionElementName="Path"
                go:Part.SelectionAdorned="True" >
    <!-- in Silverlight substitute Path for go:LinkShape -->
    <go:LinkShape x:Name="Path" go:LinkPanel.IsLinkShape="True"
                  Stroke="Black" StrokeThickness="1" />
    <Polygon Fill="Black" Points="8 4  0 8  2 4  0 0"  <!-- the arrowhead -->
             go:LinkPanel.Alignment="1 0.5" go:LinkPanel.Index="-1"
             go:LinkPanel.Orientation="Along" />
  </go:LinkPanel>
</DataTemplate>
DataTemplate for orthogonal links with an arrowhead

<DataTemplate x:Key="LinkTemplate4">
  <go:LinkPanel go:Part.SelectionElementName="Path"
                go:Part.SelectionAdorned="True">
    <go:Link.Route>
      <go:Route Routing="Orthogonal" />
    </go:Link.Route>
    <!-- in Silverlight substitute Path for go:LinkShape -->
    <go:LinkShape x:Name="Path" go:LinkPanel.IsLinkShape="True"
                  Stroke="Black" StrokeThickness="1" />
    <Polygon Fill="Black" Points="8 4  0 8  2 4  0 0"
             go:LinkPanel.Alignment="1 0.5" go:LinkPanel.Index="-1"
             go:LinkPanel.Orientation="Along" />
  </go:LinkPanel>
</DataTemplate>
Option to enable AvoidsNodes link routing

    <go:Link.Route>
      <go:Route Routing="AvoidsNodes" />
    </go:Link.Route>
Orthogonal Routing with rounded corners

    <go:Link.Route>
      <go:Route Routing="Orthogonal" Curve="JumpOver" Corner="10" />
    </go:Link.Route>
Click to Show DataTemplate XAML code
Click to Show DataTemplate XAML code
Click to Show DataTemplate XAML code
Bezier
with curviness
Rounded with Jumpovers
Option to enable Bezier curves.

    <go:Link.Route>
      <go:Route Curve="Bezier" />
    </go:Link.Route>
Option to enable Bezier curves. You can control the amount of curvature by setting the Route.Curviness property. With varying numbers of links between the same pair of nodes it will automatically compute values for Curviness unless you assign it explicitly.

    <go:Link.Route>
      <go:Route Curve="Bezier" />
    </go:Link.Route>
Orthogonal Routing with rounded corners

    <go:Link.Route>
      <go:Route Routing="Orthogonal" Curve="JumpOver" Corner="10" />
    </go:Link.Route>

Links with Annotations

It is common to add annotations or decorations to links, particularly text.  You can easily add any elements you want to a LinkPanel. (click to see XAML)

Links with labels
that follow the path of the link
Links support labels
that follow the path of the link
Label on the From and To ends of link

<DataTemplate x:Key="LinkTemplate5">
  <go:LinkPanel>
    <go:LinkShape Stroke="Black" StrokeThickness="1" />
    <Polygon Fill="Black" Points="8 4  0 8  2 4  0 0" go:LinkPanel.Index="-1"
             go:LinkPanel.Alignment="1 0.5" go:LinkPanel.Orientation="Along" />
    <TextBlock Text="From" go:LinkPanel.Index="0"
             go:LinkPanel.Offset="NaN NaN" go:LinkPanel.Orientation="Upright" />
    <TextBlock Text="To" go:LinkPanel.Index="-1"
             go:LinkPanel.Offset="NaN NaN" go:LinkPanel.Orientation="Upright" />
  </go:LinkPanel>
</DataTemplate>
even curvy paths
link labels can be any element
even curvy paths
link labels can be any element
link labels can be any element - here a red 8 pointed star and a XAML Button control are used

  <!-- LinkPanel labels in Silverlight -->
  <go:NodePanel go:LinkPanel.Index="0" go:LinkPanel.Offset="5 5" >
    <Path go:NodePanel.Figure="EightPointedStar" Fill="Red"
          Width="10" Height="10" />
  </go:NodePanel>
  <Button Content="?" Click="Button_Click" />
 
  <!-- LinkPanel labels in WPF -->
  <go:NodeShape go:LinkPanel.Index="0" go:LinkPanel.Offset="5 5"
                go:NodePanel.Figure="EightPointedStar" Fill="Red"
                Width="10" Height="10" />
  <Button Content="?" Click="Button_Click" />

Link Connection Points

By default, links will connect around the edge of a node. (click to see XAML)

links connect to edge of any shape
connect to spot
links connect to edge
of any shape
or to a specific spot
or to a one or more sides
Setting the Node.FromSpot and Node.ToSpot attached properties

<DataTemplate x:Key="NodeTemplate2">
  <TextBlock Text="{Binding Path=Data.Key}" go:Node.SelectionAdorned="True"
             go:Node.ToSpot="MiddleLeft" go:Node.FromSpot="MiddleRight" />
</DataTemplate>
You can also specify that the links go into a node not at a single spot but spread out along one side. Note we've added a border to the node here as well.

<DataTemplate x:Key="NodeTemplate3">
  <Border BorderBrush="Black" BorderThickness="1" Padding="3"
          go:Node.SelectionAdorned="True"
          go:Node.ToSpot="LeftSide" go:Node.FromSpot="RightSide" >
    <TextBlock Text="{Binding Path=Data.Key}" />
  </Border>
</DataTemplate>

There are times when you want to have different logical and graphical places at which links should connect. GoXam allows you to create a link connection spot out of any element.  The elements to which a link may connect are called ports.  There may be any number of ports in a node. (click to see XAML)

nodes with ports
nodes with ports
Nodes with ports
logic diagram with input/output ports
Gray node with 2 inputs ports and an output port

<DataTemplate x:Key="NodeTemplate4">
  <Border BorderBrush="Black" BorderThickness="1"
          go:Node.SelectionAdorned="True">
    <Grid Background="LightGray">
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="Auto" />
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
      </Grid.RowDefinitions>
      <TextBlock Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3"
                 Text="{Binding Path=Data.Key}" TextAlignment="Center"
                 FontWeight="Bold" TextWrapping="Wrap" Margin="4,4,4,2" />
      <StackPanel Grid.Column="0" Grid.Row="1" Orientation="Horizontal">
        <!-- this Rectangle is a port, identified with the string “A”;
             links only come into it at the middle of the left side -->
        <Rectangle Width="6" Height="6" Fill="Black"
                   go:Node.PortId="A" go:Node.ToSpot="MiddleLeft" />
        <TextBlock Text="A" />
      </StackPanel>
      <StackPanel Grid.Column="0" Grid.Row="2" Orientation="Horizontal">
        <!-- this Rectangle is another input port, named “B” -->
        <Rectangle Width="6" Height="6" Fill="Black"
                   go:Node.PortId="B" go:Node.ToSpot="MiddleLeft" />
        <TextBlock Text="B" />
      </StackPanel>
      <StackPanel Grid.Column="2" Grid.Row="1" Grid.RowSpan="2"
                  Orientation="Horizontal" VerticalAlignment="Center">
        <TextBlock Text="Out" />
        <!-- this Rectangle is another port, identified with the string “Out”;
             links only go out of it at the middle of the right side -->
        <Rectangle Width="6" Height="6" Fill="Black"
                   go:Node.PortId="Out" go:Node.FromSpot="MiddleRight" />
      </StackPanel>
    </Grid>
  </Border>
</DataTemplate>

 

 
for Silverlight
for WPF
 
Visual Studio Partner

 

 

Want More Detail?
Goxam Intro Documentation
Read the Intro!

 

 
Copyright © 1995-2010 Northwoods Software®. All rights reserved.