The Arrowheads sample shows all of the different values of the Arrowhead enumeration. For every two Arrowheads, a Node is created which a center Node links to. The LinkPanel.ToArrowProperty and LinkPanel.FromArrowProperty is set on each link to show every Arrowhead. The property is set through data binding on properties in the custom data classes. In the Xaml, the following markup is used.

     go:LinkPanel.ToArrow="{Binding Path=Data.ToArrow}"

In the code, the ToArrow property is defined as follows.

     private Arrowhead ToArrow { get; set; }

No special property definition is needed because the value never changes after it is set in the constructor.

This sample also shows animation of the Node.Location property. Using a Storyboard, PointAnimationUsingKeyFrames for each Node are synchronized. Each animation consists of LinearPointKeyFrames whose values are the locations of every Node. In this way, each Node moves to the location of every other Node in sequence, using linear interpolation. This motion approximates each Node moving in a circle, or a circle of Nodes rotating about its center. Since neither Silverlight 3 nor Silverlight 4 supports path animations, this workaround is necessary. The animation repeats indefinitely. This is achieved by setting the StoryBoard.RepeatBehavior to RepeatBehaviour.Forever.

Since the geometries for the Arrowheads are defined using the StreamGeometry path markup syntax, they are opaque and only their bounds can be retrieved. This lack of information makes it difficult to determine if an Arrowhead should be filled. In this sample, a custom converter is used to convert between an Arrowhead and a Brush for the Fill property. In the resources, a converter is defined. It is later used in the binding.

    <local:ArrowheadFillConverter x:Key="theArrowheadFillConverter" />

...

    Fill="{Binding Path=Data.FromArrow, Converter={StaticResource theArrowheadFillConverter}}"

In the c-sharp file, the following custom converter is defined.

    public class ArrowheadFillConverter : Converter {

        public override object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
          ...
          Arrowhead arrow = (Arrowhead)value;
          SolidColorBrush arrowFill = new SolidColorBrush(Colors.LightGray);  //If none of the below, use a LightGray brush color.
          switch (arrow) {  //All of the cases in which the fill should be null, other than those on which a non-null Fill has no effect, i.e., Arrowhead.VerticalLine.
            case Arrowhead.BackwardOpenTriangle: arrowFill = new SolidColorBrush(); break;
            ...
          }
          return arrowFill;
        }

      }

Only the cases in which setting a non-null fill would have an undesired effect are dealt with.