Differently colored links

Thanks very much, the new version can resolved my question. i am using silverlight dll, and i have an other question, i want to change the link properties on varied layout, for example:
golayout:MultiLayout
<golayout:TreeLayout Id=“Left” Angle=“180” Arrangement=“FixedRoots” SetsPortSpot=“False” ConditionFlags=“All” />
<golayout:TreeLayout Id=“Right” Angle=“0” Arrangement=“FixedRoots” SetsPortSpot=“False” ConditionFlags=“All” />
</golayout:MultiLayout>

i want to set all the “Left” layout’s link’s color is red and “Right” layout’s link’s arrow color is black. Thanks again.

Well, the most flexible strategy is to data-bind the link’s Path’s Stroke to a property on the link’s ToData, using some kind of converter.

If there were an additional property on the node data that named the color that you wanted for links that connected to that node, you could use a StringBrushConverter.

If you don’t want to add such a property, you could implement your own Converter that looked at the node data and returned the desired Brush. For example, if you wanted to modify the DoubleTree sample, you could define a Converter:

public class LinkBrushConverter : Northwoods.GoXam.Converter { public override object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { Color c = Colors.Black; if (value is String) { switch ((String)value) { case "Left": c = Colors.Red; break; case "Down": c = Colors.Blue; break; case "Up": c = Colors.Green; break; default: break; } } return new SolidColorBrush(c); } }
Then in the XAML you could create such a converter:

    <local:LinkBrushConverter x:Key="theLinkBrushConverter" />

and use it in the link’s template:

<DataTemplate x:Key="LinkTemplate"> <!-- a fairly standard "arrow-like" link template with no selection handle --> <go:LinkPanel> <Path go:LinkPanel.IsLinkShape="True" StrokeThickness="1" Stroke="{Binding Path=Link.ToData.LayoutId, Converter={StaticResource theLinkBrushConverter}}" /> <Polygon Fill="{Binding Path=Link.ToData.LayoutId, Converter={StaticResource theLinkBrushConverter}}" Points="8 4 0 8 2 4 0 0" go:LinkPanel.Index="-1" go:LinkPanel.Alignment="1 0.5" go:LinkPanel.Orientation="Along" /> </go:LinkPanel> </DataTemplate>

Big%20smile,very nice, thanks a lot, gosilverlight control is perfect!.

Hello,
I’m having almost the same case, but actually I need to set the color of the links depending on a property set in the diagram xml source file.
In other words, my xml file looks like the following:

<StateChart>

<span =“m”><<span =“t”>State <span =“t”>Key<span =“m”>=“2384<span =“m”>” <span =“t”> Location<span =“m”>=“0 0<span =“m”>”<span =“t”> Text<span =“m”>=“HE.K.B.1.1
Recognize school and community health helpers.
<span =“m”>”<span =“m”> />

<span =“b”> <span =“m”><<span =“t”>State <span =“t”>Key<span =“m”>=“2385<span =“m”>”<span =“t”>
Location<span =“m”>=“382 21<span =“m”>”<span =“t”> Text<span =“m”>=“HE.K.B.1.2 Recognize warning
labels and signs on hazardous products and places.
<span =“m”>”<span =“m”> />
<span =“m”><<span =“t”>Transition <span =“t”>From<span =“m”>=“2384<span =“m”>”<span =“t”> To<span =“m”>=“2385<span =“m”>” Category=“1”<span =“m”> />
<span =“m”><<span =“t”>Transition <span =“t”>From<span =“m”>="<span =“m”>2385<span =“m”><span =“m”><span =“m”>"<span =“t”>
To<span =“m”>=“2385<span =“m”>”
Category=“2”<span =“m”> />
<span =“m”><span =“m”></<span =“t”>StateChart<span =“m”>>

As you can see, in the transition node there is an element called “Category”.
Each transition will have a different category value. I need to display the colors depending on the category value.

Below are snippets from my code:

xaml:


<go:LinkPanel go:Link.SelectionElementName=“Path” go:Part.Reshapable=“True”>
go:Link.Route
<go:Route Curve=“Bezier” RelinkableFrom=“True” RelinkableTo=“True”
Curviness="{Binding Path=Data.Curviness}" />
</go:Link.Route>


<go:NodePanel Sizing=“Auto”>


</go:NodePanel>
</go:LinkPanel>

C#:

public class LinkBrushConverter : Northwoods.GoXam.Converter
{
public override object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Color c = Colors.Purple;
return new SolidColorBrush©;
}
}

How can I manage the function parameters’ values in order to send the category value as parameter in the function?

Thanks.

First, salemt, I assume you are using Silverlight.

You want the brush to be dependent on properties of two different objects: your LinkData.Category and the Link.IsSelected properties. The problem is that what you want is MultiBinding, but Silverlight
doesn’t support that.

The normal but convoluted solution for this is to combine the two properties into one property on one object, somehow. Since it doesn’t make sense to put the transient Part.IsSelected property on your LinkData class, we’ll do it the other way around: we’ll add a property to Link that represents both Link.IsSelected and LinkData.Category.

[code] public class CustomLink : Link {
public static readonly DependencyProperty IsSelectedColorProperty =
DependencyProperty.Register(“IsSelectedColor”, typeof(String), typeof(CustomLink), new PropertyMetadata(""));

public String IsSelectedColor {
  get { return (String)GetValue(IsSelectedColorProperty); }
  set { SetValue(IsSelectedColorProperty, value); }
}

protected override void OnIsSelectedChanged() {
  MyLinkData data = this.Data as MyLinkData;
  if (data != null) {
    if (this.IsSelected)
      this.IsSelectedColor = "!" + data.Color;
    else
      this.IsSelectedColor = data.Color;
  }
  base.OnIsSelectedChanged();
}

}[/code]
Note how when the link is selected, the property value is the regular color string prefixed with an exclamation mark. Of course you may want to do a completely different way of combining the two property values.

Now how do we get the PartManager to create CustomLink objects instead of the normal Link objects?

public class CustomPartManager : PartManager { protected override Link MakeLinkForData(object linkdata, IDiagramModel model, DataTemplate templ, string category) { CustomLink link = new CustomLink(); MyLinkData d = linkdata as MyLinkData; if (d != null) link.IsSelectedColor = d.Color; PartBinding data = new PartBinding(link, linkdata); link.Content = data; link.DataContext = data; link.ContentTemplate = templ; if (category != null && category != "") link.Category = category; return link; } }
This is the regular definition for PartManager.MakeLinkForData, but with it creating a CustomLink instead of the regular Link, and it initializes the value of the new IsSelectedColor property.

We also need to install this CustomPartManager as the Diagram’s PartManager at initialization time:

      myDiagram.PartManager = new CustomPartManager();

OK, so now we’re ready to define a String to Brush converter. The following one just produces a lighter color brush if the string starts with “!”.

public class CustomStringBrushConverter : StringBrushConverter { public override object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { String s = value as String; if (s != null && s.Length > 1 && s[0] == '!') { Color c = (Color)myStringColorConverter.Convert(s.Substring(1), typeof(Color), parameter, culture); c.R = (byte)((c.R+255)/2); c.G = (byte)((c.G+255)/2); c.B = (byte)((c.B+255)/2); return new SolidColorBrush(c); } return base.Convert(value, targetType, parameter, culture); } private StringColorConverter myStringColorConverter = new StringColorConverter(); }
Of course you’ll need to figure out what you really want to return instead of this contrived example.

Note also that since Silverlight doesn’t support a programmer callable conversion from string to color, you need to use the one that GoXam provides.

Then we can create a resource that is a CustomStringBrushConverter:

    <local:CustomStringBrushConverter x:Key="theCustomStringBrushConverter" />

And use it in your DataTemplate(s):

<DataTemplate x:Key="LinkTemplate"> <go:LinkPanel go:Part.SelectionElementName="Path" go:Part.SelectionAdorned="True"> <Path x:Name="Path" go:LinkPanel.IsLinkShape="True" Stroke="{Binding Path=Link.IsSelectedColor, Converter={StaticResource theCustomStringBrushConverter}}" 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>
So that’s quite a bit of custom code, just because Silverlight doesn’t support MultiBinding.

Thanks walter for your reply. I was trying to work as the solution provided by you but I was facing problems in

 MyLinkData data = this.Data as MyLinkData;

It always returns null value.

Anyway, is there any way that I can change one of the values of the function

public override object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
let's say to send the category as value parameter?

You need to adapt the code for your particular application. In this case, replace “MyLinkData” with your link data class. In the StateChart sample, for example, that’s “Transition”.

If you want the “value” argument of Convert to be your MyLinkData.Category value, and if you don’t care about depending on whether the Link.IsSelected, then you don’t need MultiBinding, so you don’t need all that code I just demonstrated for you.

Just bind directly to the Category property. There are lots of examples of this throughout the samples. For example:

    

    
      
        
        ...
      
    

Thanks walter. It worked