<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.3.2" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>ILOG .NET Visualization Blog</title>
	<link>http://blogs.ilog.com/netvisu</link>
	<description>Just another WordPress weblog</description>
	<pubDate>Thu, 26 Jun 2008 12:22:25 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.3.2</generator>
	<language>en</language>
			<item>
		<title>Creating Default Anchors for custom User Symbols</title>
		<link>http://blogs.ilog.com/netvisu/2008/06/26/creating-default-anchors-for-custom-user-symbols/</link>
		<comments>http://blogs.ilog.com/netvisu/2008/06/26/creating-default-anchors-for-custom-user-symbols/#comments</comments>
		<pubDate>Thu, 26 Jun 2008 12:22:25 +0000</pubDate>
		<dc:creator>Robert Dupuy</dc:creator>
		
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[Diagram]]></category>

		<guid isPermaLink="false">http://blogs.ilog.com/netvisu/2008/06/26/creating-default-anchors-for-custom-user-symbols/</guid>
		<description><![CDATA[This article describes how to create default anchors on custom user symbols with <a href="http://www.ilog.com/products/diagrammernet/">ILOG Diagrammer for .NET</a>.

First, we need to make sure that we know what anchors and user symbols are. Let's briefly define these two notions:
<ul>
	<li>A <strong>user&#8230;</strong></li></ul>]]></description>
			<content:encoded><![CDATA[<p>This article describes how to create default anchors on custom user symbols with <a href="http://www.ilog.com/products/diagrammernet/">ILOG Diagrammer for .NET</a>.</p>
<p>First, we need to make sure that we know what anchors and user symbols are. Let&#8217;s briefly define these two notions:</p>
<ul>
<li>A <strong>user symbol</strong> is a graphic object built with the<strong> </strong><span id="nsrTitle"><strong>ILOG Diagrammer for .NET Diagram Designer</strong>. This designer, fully integrated into Visual Studio, is a WYSIWYG editor that produces C# or VB.NET code. Using this editor, you can build complex interactive symbols by assembling available shapes and symbols.</span></li>
<li>An anchor is a point on a graphic object where a link can be connected. Each graphic object has a collection of anchors on which it&#8217;s possible to connect links.</li>
</ul>
<p>Now that we know what we&#8217;re talking about, we can imagine the following scenario: A user has created a custom user symbol using our designer, and he wants to specify the exact location where links could be connected to this symbol. For example, when designing an electrical symbol, one need to specify that wires can be connected to the component terminals. Here is an example of such a symbol:</p>
<p><a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/06/transistor.png" title="Transistor"><img src="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/06/transistor.png" alt="Transistor" /></a></p>
<p>Let&#8217;s create this symbol in Visual Studio:</p>
<ol>
<li>Launch Visual Studio 2005 or 2008.</li>
<li>Select <strong>File</strong>-&gt;<strong>New</strong>-&gt;<strong>Project</strong>-&gt;<strong>ILOG Diagrammer Symbol Library</strong> and name the project <strong>ElectricalSymbolsLibrary</strong>.</li>
<li>In the solution explorer, right click on the project, and choose <strong>Add New Item</strong>-&gt;<strong>UserSymbol (ILOG Diagrammer) </strong>and name the symbol <strong>Transistor.cs.</strong></li>
<li>Choose <strong>Diagrammer</strong>-&gt;<strong>Import File</strong> and import <strong>transistor.ivn</strong> after extracting it from the following <a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/06/transistor.zip">archive</a>. Click <strong>Yes</strong> in the dialog asking if you want to import the file as vector graphics.</li>
</ol>
<p>You should now have your transistor symbol visible in the designer:</p>
<p><a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/06/electrical.png" title="ILOG Diagrammer for .NET Diagram Designer"><img src="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/06/electrical.png" alt="ILOG Diagrammer for .NET Diagram Designer" /></a></p>
<p>Let&#8217;s now use this new symbol in a diagram so that we can try to connect links to it. To add a diagram to the project, right-click in the solution explorer on the project and choose <strong>Add</strong>-&gt;<strong>New Item</strong>-&gt;<strong>Diagram (ILOG Diagrammer). </strong>Compile the project (<strong>Build</strong>-&gt;<strong>Build Solution</strong>) to update the toolbox. Open the toolbox, your new transistor symbol should be available:</p>
<p><a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/06/electrical2.png" title="ILOG Diagrammer for .NET Diagram Designer"><img src="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/06/electrical2.png" alt="ILOG Diagrammer for .NET Diagram Designer" /></a></p>
<p>Drag a transistor symbol from the toolbox to the design surface. Repeat the operation to have several symbols in the diagram. You should now have something like this:</p>
<p><a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/06/electrical3.png" title="ILOG Diagrammer for .NET Diagram Designer"><img src="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/06/electrical3.png" alt="ILOG Diagrammer for .NET Diagram Designer" /></a></p>
<p>Let&#8217;s now try to connect the transistors together by creating links between them. Open the toolbox and locate the <strong>Connectors</strong> tab. Click on one of the links available in the tab, then move the mouse over one of the transistors. The anchors where the link can be connected are highlighted:</p>
<p><a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/06/electrical4.png" title="Anchors highlighted"><img src="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/06/electrical4.png" alt="Anchors highlighted" /></a></p>
<p>We can see that by default a user symbol has four anchors, each one located at the middle of the bounding box sides. Obviously, that&#8217;s not what we want here. One way to get the right anchors is to edit each transistor instance by modifying its anchors collection: After removing the default anchors (set the <strong>UseDefaultAnchors</strong> property to <strong>false</strong>), add three <strong>BoundsAnchor</strong> to the anchors collection (right-click on the transistor, and choose <strong>Edit Anchors&#8230;</strong>). Then, we need to move each anchor at the desired location. To do this, choose the <strong>Edit Anchors</strong> (<a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/06/electrical5.png" title="Edit Anchors"><img src="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/06/electrical5.png" alt="Edit Anchors" /></a>) icon from the Diagrammer toolbar and move the mouse over the transistor. It&#8217;s now possible to move the three anchors previously added to their right location by clicking each anchor and dragging it to its desired location. Then, if we go back to the link mode connection by clicking on a link in the toolbox <strong>Connectors</strong> tab, we can see by passing the mouse over it, that our transitor has now its anchors placed at their right location:</p>
<p><a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/06/electrical6.png" title="Electrical"><img src="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/06/electrical6.png" alt="Electrical" /></a></p>
<p>The main drawbacks of this approach are:</p>
<ul>
<li>The anchors are not part of the symbol itself, since they have been added after the symbol creation. If you create an instance of this symbol by code, your new anchors will not be available.</li>
<li>We&#8217;re not using the default anchors feature of the graphic objects, and thus, anchors are created and added to the component model even though there are no links connected to them. This can be a performance issue if you have many objects with many anchors.</li>
</ul>
<p>An alternative to this approach is to define the default anchors directly when designing the transistor. How can we do this ? Let&#8217;s go back to the designer view of our transistor by double clicking the <strong>Transistor.cs</strong> file in the <strong>Solution Explorer</strong>. The trick is that all the real anchors (not the default ones) defined in the sub objects of our transistor will be exposed as default anchors for our user symbol. Thus, we simply need to add three anchors on the sub objects composing our transistor. Let&#8217;s see how to do it.</p>
<p>If you look at the <strong>Document Outline</strong> view in Visual Studio, you will see that our transistor is composed of several shapes:</p>
<p><a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/06/electrical7.png" title="Electrical7"><img src="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/06/electrical7.png" alt="Electrical7" /></a></p>
<p>The interesting objects are the <strong>polyline1</strong>, <strong>polyline2</strong> and <strong>line1</strong> objects. On each one, we will add a new <strong>PolyPointsAnchor</strong>, which is a type of anchor whose location is bound to a vertex of a polyline object. Right-click on the <strong>polyline1</strong> object in the designer view, and choose  <strong>Edit Anchors</strong>. Add a <strong>PolyPointsAnchor </strong>and click the <strong>OK</strong> button. Repeat the operation for the <strong>polyline2</strong> and <strong>line1</strong> objects. Note that in our example, the anchors are located on the first vertex of each polyline, which is the default for <strong>PolyPointsAnchor</strong> objects<strong>.</strong></p>
<p>Let&#8217;s compile the project and switch back to our diagram view to test our transistor by double clicking the <strong>Diagram1.cs</strong> file in the <strong>Solution Explorer</strong>. To start with a fresh diagram, remove existing instances of the transistors. Then drag and drop a new transistor from the toolbox and try to connect a link to see that the highlighted anchors are the expected ones:</p>
<p><a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/06/electrical8.png" title="Electrical8"><img src="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/06/electrical8.png" alt="Electrical8" /></a></p>
<p>We&#8217;ve successfully changed the default anchors of our transistor, without having to write a single line of code.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ilog.com/netvisu/2008/06/26/creating-default-anchors-for-custom-user-symbols/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Creating Bezier Curves in an  Ajax DiagramView (Part 2)</title>
		<link>http://blogs.ilog.com/netvisu/2008/06/20/create-bezier-curve-in-an-ajaxdiagramview-part-2/</link>
		<comments>http://blogs.ilog.com/netvisu/2008/06/20/create-bezier-curve-in-an-ajaxdiagramview-part-2/#comments</comments>
		<pubDate>Fri, 20 Jun 2008 09:32:20 +0000</pubDate>
		<dc:creator>Patrick Ruzand</dc:creator>
		
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[Ajax]]></category>

		<category><![CDATA[Diagram]]></category>

		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blogs.ilog.com/netvisu/2008/06/20/create-bezier-curve-in-an-ajaxdiagramview-part-2/</guid>
		<description><![CDATA[<a href="http://blogs.ilog.com/netvisu/2008/06/10/creating-bezier-curves-in-an-ajax-diagramview-part-1/" title="Part 1">In the previous article</a>, I have explained the fundations of the Ajax interaction framework of <a target="_blank" href="http://www.ilog.com/products/diagrammernet/" title="ILOG Diagrammer for .NET">ILOG Diagrammer for .NET</a>. It is now time to dive into the implementation details.

From the first article, we know an <code>AjaxDiagramView</code> interactor inherits from the&#8230;]]></description>
			<content:encoded><![CDATA[<p><a href="http://blogs.ilog.com/netvisu/2008/06/10/creating-bezier-curves-in-an-ajax-diagramview-part-1/" title="Part 1">In the previous article</a>, I have explained the fundations of the Ajax interaction framework of <a target="_blank" href="http://www.ilog.com/products/diagrammernet/" title="ILOG Diagrammer for .NET">ILOG Diagrammer for .NET</a>. It is now time to dive into the implementation details.</p>
<p>From the first article, we know an <code>AjaxDiagramView</code> interactor inherits from the <code>System.Web.UI.ExtenderControl</code> class. As such, it is composed of two parts: an ASP.NET server control and a JavaScript client control.</p>
<h2>The server control</h2>
<p>The ASP.NET server control is responsible for describing the client resources to the underlying ASP.NET framework (the script resources to deploy, the optional initialization tasks to perform on the client, etc.), and for handling the possible actions coming from the client control. In our case, the server control implementation handles the client action (i.e. create an <code>ILOG.Diagrammer.Graphic.BezierCurve</code> instance and add it to the view content) via an asynchronous callback. Let&#8217;s first begin with the implementation of the client resources description.</p>
<p>For this purpose, the <code>ILOG.Diagrammer.Web.UI.ViewInteractor</code> class defines the following methods:</p>
<pre>
ScriptBehaviorDescriptor CreateScriptBehaviorDescriptor(Control targetControl)
IEnumerable&lt;ScriptReference&gt; GetScriptReferences()</pre>
<p>The <code>CreateScriptBehaviorDescriptor</code> method must be overriden to return a <code>ScriptBehaviorDescriptor</code> instance that specifies the name of the client-side class of the interactor (in other words the name of the JavaScript class).<br />
The <code>GetScriptReferences</code> method returns the script resources needed by your client control. This is needed by ASP.NET to be able to automatically deploy the required client resources.</p>
<p>Here is a first implementation of the <code>MakeBezierCurveInteractor</code> class that illustrates the implementation of these methods :</p>
<pre>
public class MakeCurveInteractor : ViewInteractor {        

  protected override ScriptBehaviorDescriptor CreateScriptBehaviorDescriptor(Control targetControl) {
    return new ScriptBehaviorDescriptor("AjaxBezierSample.MakeCurveBehavior",
                                        targetControl.ClientID);
  }                

  protected override IEnumerable&lt;scriptreference&gt; GetScriptReferences() {
    IEnumerable&lt;ScriptReference&gt; references = base.GetScriptReferences();
    List&lt;ScriptReference&gt; list = new List&lt;ScriptReference&gt;(references);
    list.Add(new ScriptReference("AjaxBezierSample.script.MakeCurveBehavior.js",
                                 Assembly.GetExecutingAssembly().FullName));
    return list;
  }</pre>
<p>which means the client control implementation is the <code>AjaxBezierSample.MakeCurveBehavior</code> class defined in the MakeCurveBehavior.js file, packaged as an embedded resource in the application assembly (packaging a script resource in the assembly requires the .js file be built with the Embedded Resource build action, and the resource declared in the AssemblyInfo.cs).</p>
<p>The next step, and it completes the server control implementation, is to handle the action. As explained above, we made the choice to process the interaction via an asynchronous ASP.NET callback, which is possible because the <code>ViewInteractor</code> base class implements the ASP.NET 2.0 <code>ICallbackEventHandler</code> interface. Therefore, our custom interactor must override the <code>ViewInteractor.RaiseCallBackEvent</code> method that is called when a callback request is received by our control.</p>
<p>The implementation is quite straightforward: it first reads the curve definition points from the method parameter (passed by the client control as a JSON string), converts these points from the view coordinate system to the view graphic container coordinate system, then creates the corresponding Diagrammer for .NET graphic object (a <code>BezierCurve</code> instance) and finally adds it to the view graphic container.</p>
<p>Here is the code:</p>
<pre>
        protected override void RaiseCallbackEvent(string eventArgument) {
            ProcessRequest(eventArgument);
            base.RaiseCallbackEvent(eventArgument);
        }
        protected virtual void ProcessRequest(string eventArgument) {
            if (string.IsNullOrEmpty(eventArgument))
                return;
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(BezierArg));
            BezierArg args = null;
            using (Stream input = new MemoryStream(Encoding.Unicode.GetBytes(eventArgument))) {
                args = serializer.ReadObject(input) as BezierArg;
            }
            if (args != null) {
                Point2D[] points = args.points;
                if (points.Length == 0)
                    return;
                Transform t = View.Transform.Inverse();
                t.TransformPoints(points);
                BezierCurve curve = new BezierCurve(points);
                IManageChildren container = View.Content as IManageChildren;
                if (container != null) {
                    container.AddChildren(new GraphicObject[] { curve });
                }
            }
        }</pre>
<p>The server control implementation is done. It&#8217;s now time to wear our JavaScript developer suit for the client side control implementation. From now on, all class names refer to the Microsoft JavaScript Library.</p>
<h2>The client control</h2>
<p>Implementing the client part of a <code>ViewInteractor</code> consists on writing a JavaScript class inheriting from the <code>ILOG.Diagrammer.Web.UI.ViewBehavior</code> class which offers the basic services to communicate with the server control. In the Microsoft JavaScript world, writing a new class consists on :</p>
<ul>
<li>defining the namespace</li>
<li>defining the class object</li>
<li>implementing the class methods via the class object prototype</li>
<li>registering the class in the class hierarchy</li>
</ul>
<p>In terms of code, it means:</p>
<ul>
<li>defining the name space:</li>
</ul>
<pre><font size="2">Type.registerNamespace(</font><font size="2" color="#a31515">&#8216;AjaxBezierSample&#8217;</font><font size="2">);</font></pre>
<p>This line of code creates a new namespace called &#8216;AjaxBezierSample&#8217; and registers it in the <code>Type</code> object.</p>
<ul>
<li>defining the class object:</li>
</ul>
<pre>AjaxBezierSample.MakeCurveBehavior = <font color="#0000ff">function</font>(element) {
  &#8230;
  AjaxBezierSample.MakeCurveBehavior.initializeBase(<font color="#0000ff">this</font>, [element]);
};</pre>
<p>The namespace object being created, we define the MakeCurveBehavior class object (the constructor) and call the initializeBase() method to initialize the base class. Latter, we will add to the constructor the fields initialization code.</p>
<ul>
<li>implementing the class methods via the class object prototype</li>
</ul>
<pre>
AjaxBezierSample.MakeCurveBehavior.prototype = {
  initialize : <font color="#0000ff">function</font>() {
    AjaxBezierSample.MakeCurveBehavior.callBaseMethod(<font color="#0000ff">this</font>, <font color="#a31515">&#8216;initialize&#8217;</font>);
  },
  dispose : <font color="#0000ff">function</font>() {
    AjaxBezierSample.MakeCurveBehavior.callBaseMethod(<font color="#0000ff">this</font>, <font color="#a31515">&#8216;dispose&#8217;</font>);
  },
  &#8230;
}</pre>
<p>The methods of the class are defined on the prototype following the prototype model. For more information on the prototype model, see the <a target="_blank" href="http://asp.net/AJAX/Documentation/Live/tutorials/CreatingClientComponentPrototype.aspx"></a>title=&#8221;Prototype model&#8221;&gt;MSDN documentation. For the time being, we only need to call the <code>initialize()</code> and <code>dispose()</code> methods of the base class.</p>
<ul>
<li>registering the class in the class hierarchy</li>
</ul>
<pre>
AjaxBezierSample.MakeCurveBehavior.registerClass(<font color="#a31515">&#8216;AjaxBezierSample.MakeCurveBehavior&#8217;</font>, ILOG.Diagrammer.Web.UI.ViewBehavior);</pre>
<p>Finally, we register our new class in the class hierarchy, specifying its fully qualified name (that is the class name prefixed with the namespace) and the base class it inherits from. This skeleton is the minimum code required to fully define a new <code>ViewBehavior</code> subclass.</p>
<p>The last step is to eventually implement the code needed to create bezier curves.</p>
<h2>Drawing Bezier curves in DHTML</h2>
<p>As explained in the first part of this article, the interaction ghost of the bezier curves will be implemented either in VML or SVG depending on the browser. The ghost will be composed of three primitive objects:</p>
<ul>
<li>a circle that represents the edited passage point.</li>
<li>two rectangles that represent the control points.</li>
</ul>
<p>These primitives will be added to a parent container positionned in absolute above the image. To ease the primitives update, both the primitives and the container will have a corresponding class field (a reference to the corresponding node in the DOM).</p>
<p>The code below shows the updated constructor (with the primitive fields) and the DOM initialization :</p>
<pre>
AjaxBezierSample.MakeCurveBehavior = function(element) {
    this._ghostContainer = null;
    this._ptMarker = null;
    this._ctrl1 = null;
    this._ctrl2 = null;
    this._useVML = Sys.Browser.agent == Sys.Browser.InternetExplorer;
    this._curveCount = 0;
    this._svg  = null;
    ...
    AjaxBezierSample.MakeCurveBehavior.initializeBase(this, [element]);
};        

AjaxBezierSample.MakeCurveBehavior.prototype = {        

    initialize : function() {
        AjaxBezierSample.MakeCurveBehavior.callBaseMethod(this, 'initialize');
        ...
        this.initDOM();
    },
    initDOM : function() {
        this._ghostContainer = document.createElement("div");
        this.get_element().appendChild(this._ghostContainer);
        this._ghostContainer.style.zIndex = 3;
        this._ghostContainer.style.position = "absolute";
        this._ghostContainer.style.left="0px";
        this._ghostContainer.style.top="0px";
        this._ghostContainer.style.width="100%";
        this._ghostContainer.style.height="100%";
        if (!this._useVML) {
            this._svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
            this._ghostContainer.appendChild(this._svg);
        }
        var parentNode = this._useVML ? this._ghostContainer : this._svg;
        // passage point marker
        this._ptMarker = this.createMarker(parentNode);
        // control points markers
        this._ctrl1 = this.createControlPt(parentNode, 'ctrl1');
        this._ctrl2 = this.createControlPt(parentNode, 'ctrl2');
    },        

    createMarker : function(parentNode) {
        var marker = this._useVML ? this._createMarkerVML(parentNode) : this._createMarkerSVG(parentNode);
        return marker;
    },        

    _createMarkerVML : function(parentNode) {
        var marker = document.createElement("oval");
        parentNode.appendChild(marker);
        marker.id = "ptmarker";
        marker.style.behavior = "url(#default#VML)";
        marker.strokeweight = 1;
        marker.filled = 'true';
        marker.fillcolor = 'black';
        marker.style.position = "absolute";
        marker.style.width = "7px";
        marker.style.height = "7px";
        marker.style.display='none';
        return marker;
    },        

    _createMarkerSVG : function(parentNode) {
        var marker = document.createElementNS("http://www.w3.org/2000/svg", "circle");
        parentNode.appendChild(marker);
        marker.style.display = 'none';
        marker.setAttributeNS(null, 'id', "ptmarker");
        marker.setAttributeNS(null, 'r', 3);
        marker.setAttributeNS(null, "fill", 'black');
        marker.setAttributeNS(null, "stroke", "none");
        return marker;
    },        

    createControlPt : function(parentNode, id) {
        var ctrl = this._useVML ? this._createControlVML(parentNode, id) : this._createControlSVG(parentNode, id);
        return ctrl;
    },        

    _createControlVML : function(parentNode, id) {
        var ctrl = document.createElement("rect");
        parentNode.appendChild(ctrl);
        ctrl.id = id;
        ctrl.style.behavior = "url(#default#VML)";
        ctrl.strokeweight = 1;
        ctrl.filled = 'false';
        ctrl.style.position = 'absolute';
        ctrl.style.width = '11px';
        ctrl.style.height = '11px';
        ctrl.style.display='none';
        return ctrl;
    },        

    _createControlSVG : function(parentNode, id) {
        var ctrl = document.createElementNS("http://www.w3.org/2000/svg", "rect");
        parentNode.appendChild(ctrl);
        ctrl.id = id;
        ctrl.setAttributeNS(null, "width", "11px");
        ctrl.setAttributeNS(null, "height", "11px");
        ctrl.setAttributeNS(null, "stroke-width", 1);
        ctrl.setAttributeNS(null, "fill", "none");
        ctrl.setAttributeNS(null, "stroke", "black");
        ctrl.style.display='none';
        return ctrl;
    },</pre>
<h2>Handling interactions</h2>
<p>The interaction process follows the following sequences:</p>
<ul>
<li>When the left mouse button is pressed, a new passage point and two control points are created.</li>
<li>When the mouse is dragged, the position of the control points is adjusted accordingly.</li>
<li>On a double-click, the curve is validated and a request is sent to the server with the curve points.</li>
<li>When the ESC key is pressed, the interaction is cancelled.</li>
</ul>
<p>Therefore, the interactor has to listen the mousedown, mousemove, mouseup and keydown events. For this purpose, we define four handlers that will be wired/unwired depending on the value of the <code>active</code> property.</p>
<p>The code below shows the handler initialization and the required methods to wire/unwire the handlers on a <code>active</code> property change:</p>
<pre>
AjaxBezierSample.MakeCurveBehavior = function(element) {        

    this._mouseDownHandler = null;
    this._mouseMoveHandler = null;
    this._mouseUpHandler = null;
    this._keyDownHandler = null;
    this._propertyChangedHandler = null;
    this._startPoint = null;
    this._points = null;
    this._size = 0;
    ...        

    AjaxBezierSample.MakeCurveBehavior.initializeBase(this, [element]);
};
AjaxBezierSample.MakeCurveBehavior.prototype = {        

    initialize : function() {
        /// <summary></summary>
        /// Initializes a MakeCurveBehavior instance.
        ///         

        AjaxBezierSample.MakeCurveBehavior.callBaseMethod(this, &#8216;initialize&#8217;);        

        this._mouseDownHandler = Function.createDelegate(this, this._onMouseDown);
        this._mouseMoveHandler = Function.createDelegate(this, this._onMouseMove);
        this._mouseUpHandler = Function.createDelegate(this, this._onMouseUp);
        this._keyDownHandler = Function.createDelegate(this, this._onKeyDown);
        this._doubleClickHandler = Function.createDelegate(this, this._onDoubleClick);
        if (this.get_active()) {
            this._wireHandlers();
        }
        this._propertyChangedHandler = Function.createDelegate(this, this._onPropertyChanged);
        this.add_propertyChanged(this._propertyChangedHandler);
        &#8230;
    },        

    dispose : function() {
        this._imgElt = null;
        $clearHandlers(this.get_element());
        AjaxBezierSample.MakeCurveBehavior.callBaseMethod(this, &#8216;dispose&#8217;);
    },        

    _wireHandlers : function() {
        $addHandler(this.get_element(), &#8216;mousedown&#8217;, this._mouseDownHandler);
        $addHandler(this.get_element(), &#8216;mousemove&#8217;, this._mouseMoveHandler);
        $addHandler(this.get_element(), &#8216;mouseup&#8217;, this._mouseUpHandler);
        $addHandler(this.get_element(), &#8216;keydown&#8217;, this._keyDownHandler);
        $addHandler(this.get_element(), &#8216;dblclick&#8217;, this._doubleClickHandler);
        this.ensureFirefoxKeyEvents();
    },        

    _unwireHandlers : function() {
        $removeHandler(this.get_element(), &#8216;mousedown&#8217;, this._mouseDownHandler);
        $removeHandler(this.get_element(), &#8216;mousemove&#8217;, this._mouseMoveHandler);
        $removeHandler(this.get_element(), &#8216;mouseup&#8217;, this._mouseUpHandler);
        $removeHandler(this.get_element(), &#8216;keydown&#8217;, this._keyDownHandler);
        $removeHandler(this.get_element(), &#8216;dblclick&#8217;, this._doubleClickHandler);
    },        

    _onPropertyChanged : function(sender, args) {
        if (&#8217;active&#8217; == args.get_propertyName()) {
            if (this.get_active()) {
                this._wireHandlers();
            } else {
                this._unwireHandlers();
            }
        }
    },</pre>
<p>Next, we need to handle the points and create the ghost curve. For this purpose, all the points (the passage points and the control points) are stored in an array in the following sequence : the passage point, the first control point, the second control point. We hence have three indices per point.</p>
<p>The code below illustrates this (for the sake of readability, the method updateCurveGhostPoints() that updates the ghost position is not shown. Please refer to the source code for more details). When the mouse is pressed, the addPoint() method is invoked to add a new passage point and two control points. The three points have initially the same coordinates until the next mouse drag. Then, when the mouse is dragged, the control points position is adjusted proportionally (in the react() method) :</p>
<pre>
    _onMouseDown : function(e) {
        if (e.button == Sys.UI.MouseButton.leftButton) {        

            if (this._points == null) {
                this._points = [];
                this._size = 0;
            }
            this._dragging = true;
            var loc = Sys.UI.DomElement.getLocation(this.get_element());
            var p = {'x':e.clientX - loc.x, 'y':e.clientY - loc.y };
            // Add the new point
            this._addPoint(p);
            // ... and compute the control points
            this._react(p);
            // update ghost
            if (this._size == 0) {
                this.updateCurveGhostPoints();
            } else {
                this._points[this._size-1] = p;
                this.addNewCurve();
            }
            this.updateMarkerPos(p);
            this.onStartInteraction();        

            e.stopPropagation();
            e.preventDefault();
        }
    },        

    _onMouseMove : function(e) {
        if (this._size &gt; 0 &amp;&amp; this._dragging) {
            var loc = Sys.UI.DomElement.getLocation(this.get_element());
            var p = {'x':e.clientX - loc.x, 'y':e.clientY - loc.y };
            if (this._size == 1) {
                // If user is dragging the starting point, add the second point.
                this._addPoint(p);
                // and compute the control points
                this._react(p);
            } else {
                // computes the control points position
                this._react(p);
                this._points[this._size-1] = p;
            }
            // update ghost
            this.updateCurveGhostPoints();        

            e.stopPropagation();
            e.preventDefault();
        }
    },        

    _addPoint : function(p) {
        if (this._size &gt; 1) {
            this._points[(++this._size)-1] = p;
            this._points[(++this._size)-1] = p;
            this._points[(++this._size)-1] = p;
        } else {
            this._points[(++this._size)-1] = p; // start point
        }
    },        

    _react : function(p) {
        if (this._size &gt; 3) {
           // Updates the position of the control point.
           var prevp = this._size - 3; // previous left handle
           var pivot = this._size - 2; // previous end point
           this._points[prevp] = this.symmetric(this._points[pivot], p);
        }
    },        

    _onMouseUp : function(e) {
        this._dragging = false;        

    },        

    _onDoubleClick : function(e) {
        if (this._points != null) {
            // Commit the action.
            this.doCreateCurve();
            this.onEndInteraction();
            this.reset();        

            e.stopPropagation();
            e.preventDefault();
        }
    },        

    _onKeyDown : function(e) {
        if (this._points != null &amp;&amp; e.keyCode == Sys.UI.Key.esc) {
            // Cancel interaction
            this.onEndInteraction();
            this.reset();
            e.stopPropagation();
            e.preventDefault();
        }
    },</pre>
<h2>Commit the new curve to the server</h2>
<p>Finally, the points defining the new curve are sent to the server-side part of our interactor to create the corresponding <code>ILOG.Diagrammer.Graphic.BezierCurve</code> object and add it to the view <code>GraphicContainer</code>. To do this, we create an asynchronous ASP.NET callback invoking the <code>ViewBehavior.callServerAsync</code> method passing the points array as parameter. At this time, the request has been processed but the image has not been updated to show the new content. In order to fix this, we override the ViewBehavior.onCallbackReceived method to refresh the view when the callback response is received :</p>
<pre>
    doCreateCurve : function() {
        var args = {};
        if (this._size &gt; 4) {
            // get rid of the extra passage point coming from the double-click.
            if (this._useVML)
                args.points = this._points.slice(0, this._points.length-1-3);
            else // under FF, we get one more mouse-down from the double-click
                args.points = this._points.slice(0, this._points.length-1-2*3);
        } else {
            args.points = this._points.slice(0);
        }
        this.callServerAsync(args);
    },        

    onCallbackReceived : function(args) {
        this.updateView();
    },</pre>
<p>You can find the VS2008 project here: <a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/06/ajaxbeziersample.zip" title="AjaxBezierSample VS2008 Project">AjaxBezierSample VS2008 Project</a>. Do not hesitate to look at the MakeCurveBehavior.js file to see how the the primitives points are updated.</p>
<p>The purpose of this implementation being a tutorial, many improvements are still to be done. For example, you could add properties to be able to customize the ghost rendering (the stroke color, the stroke style, etc.), an optional PostBack behavior (see ViewBehavior.doPostBack() method), additional editing capabilities (add/supress points or closed curves support).</p>
<p>As you can see, writing a new interactor for an AjaxDiagramView is essentially a client-side task. Fortunately, the Microsoft JavaScript Library and the ILOG.Diagrammer.Web.UI.ViewBehavior class provide a rich set of functionalities and services that make the JavaScript implementation easier and poweful. Also, the use of asynchronous callbacks to handle the interaction allows a very smooth user experience avoiding the annoying cost of a PostBack.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ilog.com/netvisu/2008/06/20/create-bezier-curve-in-an-ajaxdiagramview-part-2/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Creating a Nice Diagram Display with WPF :  It&#8217;s So Easy</title>
		<link>http://blogs.ilog.com/netvisu/2008/06/18/creating-a-nice-diagram-display-with-wpf-its-so-easy/</link>
		<comments>http://blogs.ilog.com/netvisu/2008/06/18/creating-a-nice-diagram-display-with-wpf-its-so-easy/#comments</comments>
		<pubDate>Wed, 18 Jun 2008 20:26:23 +0000</pubDate>
		<dc:creator>Ed Kiraly</dc:creator>
		
		<category><![CDATA[Diagram]]></category>

		<category><![CDATA[Visual Studio]]></category>

		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://blogs.ilog.com/netvisu/2008/06/18/creating-a-nice-diagram-display-with-wpf-its-so-easy/</guid>
		<description><![CDATA[In this short 7 minute presentation, Patrick Megard leads us through the basic steps in creating a diagram display using ILOG Diagrammer for .NET's and Visual Studio 2008's WPF features.

<em>The following movie is best viewed in full screen mode:</em>
<p align="center">&#160;</p>
<em>Presented&#8230;</em>]]></description>
			<content:encoded><![CDATA[<p>In this short 7 minute presentation, Patrick Megard leads us through the basic steps in creating a diagram display using ILOG Diagrammer for .NET&#8217;s and Visual Studio 2008&#8217;s WPF features.</p>
<p><em>The following movie is best viewed in full screen mode:</em></p>
<p align="center">&nbsp;</p>
<p><embed enablejs="true" overstretch="true" allowfullscreen="true" allowscriptaccess="always" flashvars="file=http://visudemos.ilog.com/videos/WPFandD4NET.flv&amp;displayheight=360" height="360" width="522" src="http://visudemos.ilog.com/videos/mediaplayer.swf" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed><em>Presented by Patrick Megard.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ilog.com/netvisu/2008/06/18/creating-a-nice-diagram-display-with-wpf-its-so-easy/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Creating Bezier curves in an Ajax DiagramView (Part 1)</title>
		<link>http://blogs.ilog.com/netvisu/2008/06/10/creating-bezier-curves-in-an-ajax-diagramview-part-1/</link>
		<comments>http://blogs.ilog.com/netvisu/2008/06/10/creating-bezier-curves-in-an-ajax-diagramview-part-1/#comments</comments>
		<pubDate>Tue, 10 Jun 2008 13:39:35 +0000</pubDate>
		<dc:creator>Patrick Ruzand</dc:creator>
		
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[Ajax]]></category>

		<category><![CDATA[Diagram]]></category>

		<guid isPermaLink="false">http://blogs.ilog.com/netvisu/2008/06/10/creating-bezier-curves-in-an-ajax-diagramview-part-1/</guid>
		<description><![CDATA[In this series of two articles, I am going to show how to create a new interactor for the  <a href="http://www.ilog.com/products/diagrammernet/" title="ILOG Diagrammer for .NET 1.5">ILOG Diagrammer for .NET 1.5</a> AjaxDiagramView web control. To illustrate this, we will write an interactor to be able to create Bezier curves&#8230;]]></description>
			<content:encoded><![CDATA[<p>In this series of two articles, I am going to show how to create a new interactor for the  <a href="http://www.ilog.com/products/diagrammernet/" title="ILOG Diagrammer for .NET 1.5">ILOG Diagrammer for .NET 1.5</a> AjaxDiagramView web control. To illustrate this, we will write an interactor to be able to create Bezier curves within the browser. I will first introduce the concepts involved in the Ajax interactions implementation (in the part 1) and then explain the implementation following a step-by-step approach. The latter will be the purpose of the second part.</p>
<p>ILOG Diagrammer for .NET 1.5 supports Ajax editing capabilities by means of a set of predefined interaction tools (called interactor) and provides an extensible framework to implement your own interactor. The interactor framework is based on <a href="http://asp.net/ajax/" title="ASP.NET AJAX">Microsoft ASP.NET AJAX</a>, the Microsoft Ajax extension which is now part of the .NET framework since the 3.5 release. This new extension introduces new ASP.NET classes that allow to easily attach client-side behaviors (implemented in JavaScript) to a web control. Such client-side extensions of a web control are called Extender Control and described by the <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.extendercontrol.aspx" title="ExtenderControl">System.Web.UI.ExtenderControl </a>class (from the System.Web.Extensions dll).<br />
The purpose of this abstract class is to &#8220;enable you to programmatically add AJAX functionality to an ASP.NET server control.&#8221; (from the MSDN documentation). Basically, this class which inherits from the System.Web.UI.Control class defines new methods whose purpose is to register the required JavaScript resources to be deployed on the client. It also provides a description of the client-side class  and the possible initialization tasks (the purpose of the GetScriptDescriptors() method).<br />
To implement the client-side control of an ExtenderControl, the ASP.NET AJAX extension (and the .NET Framework 3.5) provides a very rich JavaScript class hierarchy by means of the Microsoft Ajax Library.  From this class hierarchy, the Sys.UI.Behavior class is the base class for ExtenderControl client implementations.</p>
<p>So, how does all this work in ILOG Diagrammer for .NET ? In fact, interactors are implemented as Extender controls (they inherits from System.Web.UI.ExtenderControl) via the ILOG.Diagrammer.Web.UI.ViewInteractor class. In addition to implementing the ExtenderControl abstract class, this class provides facilities to process the interaction on the server either via a postback (it implements <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.ipostbackeventhandler.aspx" title="IPostBackEventHandler">IPostBackEventHandler</a>) or an async callback (it implements also <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.icallbackeventhandler.aspx" title="ICallbackEventHandler">ICallbackEventHandler</a>).</p>
<p>Now the foundations are cristal-clear :-), let&#8217;s focus on our interactor. As initially mentioned, the goal is to be able to create Bezier curves within the browser. That means the user will define the passage points and control points by clicking within the AjaxDiagramView and once the interaction ends, the points will be sent to the server so that our interactor server implementation processes the data and creates a new ILOG.Diagrammer.Graphic.Curve objects and adds it to the view graphic container. Also, to reduce flickering effects, the request will be performed via an async callback.</p>
<p>Finally, one last point before we start coding. To improve the user experience, we want to draw a visual feedback of the curve being edited. So how to render bezier curves in a browser ? The idea is to use a vector graphic rendering engine from the browser. There are several solutions for that but unfortunately none are cross-browser so we will have to make browser-specific implementations. Under IE, we will use inline <a href="http://www.w3.org/TR/NOTE-VML" title="VML Specification">VML</a> which is natively supported by IE. Under Firefox, we will use inline <a href="http://www.w3.org/TR/SVG/" title="SVG Specification">SVG</a>. Now we have our inline vector graphic APIs for the browsers, we are ready to start the implementation.</p>
<p>Note: the second article can be found <a href="http://blogs.ilog.com/netvisu/2008/06/20/create-bezier-curve-in-an-ajaxdiagramview-part-2/" title="Part 2">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ilog.com/netvisu/2008/06/10/creating-bezier-curves-in-an-ajax-diagramview-part-1/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Displaying a Microsoft Project XML file using Diagrammer for .NET, WPF and LinQ (Part 2)</title>
		<link>http://blogs.ilog.com/netvisu/2008/05/29/displaying-a-microsoft-project-xml-file-using-diagrammer-for-net-wpf-and-linq-part-2/</link>
		<comments>http://blogs.ilog.com/netvisu/2008/05/29/displaying-a-microsoft-project-xml-file-using-diagrammer-for-net-wpf-and-linq-part-2/#comments</comments>
		<pubDate>Thu, 29 May 2008 13:55:57 +0000</pubDate>
		<dc:creator>Emmanuel Tissandier</dc:creator>
		
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[Diagram]]></category>

		<category><![CDATA[Linq]]></category>

		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://blogs.ilog.com/netvisu/2008/05/29/displaying-a-microsoft-project-xml-file-using-diagrammer-for-net-wpf-and-linq-part-2/</guid>
		<description><![CDATA[In the <a href="http://blogs.ilog.com/netvisu/2008/05/19/displaying-a-microsoft-project-xml-file-using-diagrammer-for-net-wpf-and-linq-part-1/">part 1</a> of this post, we have seen how to use <a href="http://www.ilog.com/products/diagrammernet">ILOG Diagrammer for .NET</a>, WPF and Linq to display the content of a Microsoft Project XML file into a graph showing the tasks and the constraints between them,&#8230;]]></description>
			<content:encoded><![CDATA[<p>In the <a href="http://blogs.ilog.com/netvisu/2008/05/19/displaying-a-microsoft-project-xml-file-using-diagrammer-for-net-wpf-and-linq-part-1/">part 1</a> of this post, we have seen how to use <a href="http://www.ilog.com/products/diagrammernet">ILOG Diagrammer for .NET</a>, WPF and Linq to display the content of a Microsoft Project XML file into a graph showing the tasks and the constraints between them, we are now going to see how to use more WPF features to display the critical path of the project.<br />
The critical path of the project is simply the set of tasks that are critical. The task is considered as critical if a delay in the task will delay the end of the project. This set of tasks and the constraints between them usually creates a path in the network, called the critical path although sometime you might see several paths.<br />
For our example, we will fist try to display the critical tasks with a red background and give some information on different type of tasks.</p>
<p>We add 3 new boolean properties to our Task class, a Milestone property for tasks that are milestones, a Summary property for tasks that represents a group of tasks, and a Critical property for critical tasks.</p>
<pre>
 public bool Milestone { get; set; }
 public bool Summary { get; set; }
 public bool Critical { get; set; }</pre>
<p>and we change the Linq query to fill these properties from the XML file:</p>
<pre>
project.Tasks
      = (from task in document.Descendants("{http://schemas.microsoft.com/project}Task")
          where (int)task.Element("{http://schemas.microsoft.com/project}ID") != 0
          select new Task()
           {
               Project = project,
               UID = (int)task.Element("{http://schemas.microsoft.com/project}UID"),
               Name = (string)task.Element("{http://schemas.microsoft.com/project}Name"),
               Start = (DateTime)task.Element("{http://schemas.microsoft.com/project}Start"),
               Finish = (DateTime)task.Element("{http://schemas.microsoft.com/project}Finish"),
               <strong>Milestone = (bool)task.Element(&#8221;{http://schemas.microsoft.com/project}Milestone&#8221;),
               Critical = (bool)task.Element(&#8221;{http://schemas.microsoft.com/project}Critical&#8221;),
               Summary = (bool)task.Element(&#8221;{http://schemas.microsoft.com/project}Summary&#8221;),</strong>
               PredecessorLinks =
                         (from link in task.Descendants(&#8221;{http://schemas.microsoft.com/project}PredecessorLink&#8221;)
                         select
                           new PredecessorLink
                           {
                               PredecessorUID = (int)link.Element(&#8221;{http://schemas.microsoft.com/project}PredecessorUID&#8221;)
                           }).ToList() 

              }).ToList();</pre>
<p>Now that our Task has 3 new properties we can modify the style of nodes with data triggers to take advantage of this. The data trigger in a style will allow changing the style depending on data. In our case, milestones will be white, summary tasks in blue and all critical tasks in red.<br />
Here is the new style for nodes with 3 data triggers.</p>
<pre>
 &lt;Style TargetType="{x:Type ilog:Node}" &gt;
     &lt;Setter Property="Background" Value="#FFF0A5"/&gt;
     &lt;Setter Property="BorderBrush" Value="#468966"/&gt;
     &lt;Setter Property="BorderThickness" Value="1"/&gt; 

     <strong>&lt;Style.Triggers&gt; 

        &lt;DataTrigger Binding=&#8221;{Binding Summary}&#8221; Value=&#8221;true&#8221;&gt;
           &lt;Setter Property=&#8221;Background&#8221; Value=&#8221;blue&#8221;/&gt;
        &lt;/DataTrigger&gt; 

        &lt;DataTrigger Binding=&#8221;{Binding Milestone}&#8221; Value=&#8221;true&#8221;&gt;
           &lt;Setter Property=&#8221;Background&#8221; Value=&#8221;white&#8221;/&gt;
           &lt;Setter Property=&#8221;CornerRadius&#8221; Value=&#8221;10&#8243;/&gt;
        &lt;/DataTrigger&gt; 

        &lt;DataTrigger Binding=&#8221;{Binding Critical}&#8221; Value=&#8221;true&#8221;&gt;
           &lt;Setter Property=&#8221;Background&#8221; Value=&#8221;red&#8221;/&gt;
        &lt;/DataTrigger&gt; 

      &lt;/Style.Triggers&gt;</strong>
 &lt;/Style&gt;</pre>
<p>The definition of data triggers is very straight forward. The data trigger evaluates the value specified by the Binding (for example {Binding Summary}) and see if it matches the value specified in the Value property (in our case true), if the two things match, then the setters are applied, in our case the background color is changed.</p>
<p>Two things to understand here, first the binding specified in the data trigger is evaluated on the data context of the Node. In the <strong>Diagram</strong> control the data context for node is the item in the data source, in our case a Task object, that is why I can directly bind to the properties of a Task (like {Binding Milestone}), no need to specify any source for the binding.<br />
The second point is the order of the triggers. I place the last trigger that changes the background to red for critical tasks at the end because a milestone or a summary task can also be critical. The last data trigger will win in such a case and thus all critical tasks will be red.<br />
We now have the following result, showing the critical tasks :</p>
<p><a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/05/diagram3.png" title="diagram3.png"><img src="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/05/diagram3.png" alt="Critical Path" /></a></p>
<p>We can also use data triggers in data templates. For example, for a milestone task it is not necessary to display the start and finish date since the dates are the same.<br />
In order to achieve this we add a data trigger in the data template of nodes:</p>
<pre>
&lt;DataTemplate x:Key="TaskTemplate"&gt;
  &lt;Grid  Margin="5" MaxWidth="150" x:Name="grid"&gt;
    &lt;Grid.RowDefinitions&gt;
      &lt;RowDefinition/&gt;
      &lt;RowDefinition/&gt;
      &lt;RowDefinition/&gt;
    &lt;/Grid.RowDefinitions&gt;
    &lt;TextBlock
       x:Name="header" Grid.Row ="0"
       Text="{Binding Path=Name}"
       TextWrapping="WrapWithOverflow"
       Foreground="#FFB03B"
       FontWeight="Bold"/&gt;
    &lt;StackPanel x:Name="startField"  Grid.Row ="1" Orientation="Horizontal"&gt;
      &lt;TextBlock x:Name="startLabel" Text="Start:"/&gt;
      &lt;TextBlock Text="{Binding Path=Start}"/&gt;
    &lt;/StackPanel&gt;
    &lt;StackPanel x:Name="finishField" Grid.Row ="2" Orientation="Horizontal"&gt;
      &lt;TextBlock x:Name="finishLabel" Text="Finish:"/&gt;
      &lt;TextBlock Text="{Binding Path=Finish}"/&gt;
    &lt;/StackPanel&gt;
  &lt;/Grid&gt;
  <strong>&lt;DataTemplate.Triggers&gt;
    &lt;DataTrigger Binding=&#8221;{Binding Milestone}&#8221; Value=&#8221;true&#8221;&gt;
        &lt;Setter TargetName=&#8221;startLabel&#8221; Property=&#8221;Text&#8221; Value=&#8221;Milestone Date:&#8221;/&gt;
        &lt;Setter TargetName=&#8221;finishField&#8221; Property=&#8221;Visibility&#8221; Value=&#8221;Collapsed&#8221;/&gt;
    &lt;/DataTrigger&gt;
  &lt;/DataTemplate.Triggers&gt; </strong>
&lt;/DataTemplate&gt;</pre>
<p>The trigger here applies to task with Milestone property set to true, it changes the label of the start date to &#8220;Milestone Date&#8221; and hides the part that corresponds to the end date.</p>
<p>Here is the result for a one of the milestones:</p>
<p><a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/05/diagram4.png" title="diagram4.png"><img src="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/05/diagram4.png" alt="Templated Milestone" /></a></p>
<p>Let&#8217;s now use data triggers for links. In order to make the critical path more obvious, we will try to draw the links between two critical tasks in red. Painting a critical task in red was easy; we have simply added a data trigger in the style. For links it is a little bit more complex because there is no instance in the data source that represents a link. To answer this problem, The Wpf diagram component creates a convenient data context for each link that is an instance of the class <strong>Diagram.LinkContext</strong>. This class has two properties, <strong>StartItem</strong> and <strong>EndItem</strong> that represents the items in the data source (for us the tasks) that are at the displayed at the begining and end of the link. Thus we can easily use data triggers in a link of the diagram.<br />
We want the link to be red if both the origin and destination tasks are critical, so we need to use a <strong>MultiDataTrigger</strong> that is a kind of data trigger with multiple conditions:</p>
<p>Here is the new style for links:</p>
<pre>
&lt;Style TargetType="{x:Type ilog:Link}" &gt;
  &lt;Setter Property="Radius" Value="10"/&gt;
  &lt;Setter Property="Stroke" Value="#FFF0A5"/&gt;
  &lt;Setter Property="StrokeThickness" Value="2"/&gt;
  &lt;Setter Property="StartArrow"&gt;
    &lt;Setter.Value&gt;
      &lt;ilog:LinkArrow  Fill="White"  Shape="Circle"/&gt;
    &lt;/Setter.Value&gt;
  &lt;/Setter&gt;
  &lt;Setter Property="EndArrow"&gt;
    &lt;Setter.Value&gt;
      &lt;ilog:LinkArrow Fill="{x:Null}"  Shape="Open"/&gt;
    &lt;/Setter.Value&gt;
  &lt;/Setter&gt;
  <strong>&lt;Style.Triggers&gt;
    &lt;MultiDataTrigger&gt;
      &lt;MultiDataTrigger.Conditions&gt;
        &lt;Condition Binding=&#8221;{Binding StartItem.Critical}&#8221; Value=&#8221;true&#8221;/&gt;
        &lt;Condition Binding=&#8221;{Binding EndItem.Critical}&#8221; Value=&#8221;true&#8221;/&gt;
      &lt;/MultiDataTrigger.Conditions&gt;
      &lt;Setter Property=&#8221;Stroke&#8221;  Value=&#8221;red&#8221;/&gt;
      &lt;Setter Property=&#8221;StrokeThickness&#8221;  Value=&#8221;3&#8243;/&gt;
    &lt;/MultiDataTrigger&gt;</strong>
  &lt;/Style.Triggers&gt;
&lt;/Style&gt;</pre>
<p>I hope I have shown how the combination of the diagram control with its graph layout algorithms and the styling and templating features of WPF can help to easily create nice looking diagrams.</p>
<p>If you want to test the project, <a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/05/criticalpath.zip" title="Project files">here is the source code</a> and Visual Studio 2008 solution. In order to compile and run you will need and evaluation of ILOG Diagrammer for .NET that you can get at <a href="http://www.ilog.com/products/diagrammernet/eval">http://www.ilog.com/products/diagrammernet/eval</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ilog.com/netvisu/2008/05/29/displaying-a-microsoft-project-xml-file-using-diagrammer-for-net-wpf-and-linq-part-2/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Licensing in .NET explained - Part 2</title>
		<link>http://blogs.ilog.com/netvisu/2008/05/22/licensing-in-net-explained-part-2/</link>
		<comments>http://blogs.ilog.com/netvisu/2008/05/22/licensing-in-net-explained-part-2/#comments</comments>
		<pubDate>Thu, 22 May 2008 09:21:16 +0000</pubDate>
		<dc:creator>Robert Dupuy</dc:creator>
		
		<category><![CDATA[.NET]]></category>

		<guid isPermaLink="false">http://blogs.ilog.com/netvisu/2008/05/22/licensing-in-net-explained-part-2/</guid>
		<description><![CDATA[In the <a href="http://blogs.ilog.com/netvisu/2008/05/13/licensing-in-net-explained-part-1/">first part of this article</a>, we've seen how to deal with licensed components from the user point of view. In the second part, I'll try to explain the whole licensing process, that is:
<ol>
	<li>Authoring licensed components.</li>
	<li>Creating licences at&#8230;</li></ol>]]></description>
			<content:encoded><![CDATA[<p>In the <a href="http://blogs.ilog.com/netvisu/2008/05/13/licensing-in-net-explained-part-1/">first part of this article</a>, we&#8217;ve seen how to deal with licensed components from the user point of view. In the second part, I&#8217;ll try to explain the whole licensing process, that is:</p>
<ol>
<li>Authoring licensed components.</li>
<li>Creating licences at design-time.</li>
<li>Creating licences at compile-time.</li>
<li>Creating licences at run-time.</li>
</ol>
<h2>Authoring licensed components</h2>
<p>I&#8217;ll not spend too much time on that topic, as it&#8217;s widely documented on the web (see for example <a href="http://msdn.microsoft.com/en-us/library/fe8b1eh9.aspx">this article</a>).</p>
<p>The process is simple. After creating your component, you have to:</p>
<ol>
<li>Apply a <a href="http://msdn2.microsoft.com/en-us/library/system.componentmodel.licenseproviderattribute(VS.71).aspx" onclick="javascript:Track('ctl00_rs1_mainContentContainer_ctl00|ctl00_rs1_mainContentContainer_ctl02',this);" id="ctl00_rs1_mainContentContainer_ctl02">LicenseProviderAttribute</a> to the class.</li>
<li>Call <a href="http://msdn2.microsoft.com/en-us/library/system.componentmodel.licensemanager.validate(VS.80).aspx">LicenseManager.Validate</a> from the class constructor to get a licence.</li>
<li>Dispose the licence in the component finalizer.</li>
</ol>
<p>The licence provider specified by the <strong>LicenseProviderAttribute</strong> attribute in step 1 is used during step 2: Calling <strong>LicenseManager.Validate</strong> in your component constructor will create an instance of this license provider, and will call its <a href="http://msdn2.microsoft.com/en-us/library/system.componentmodel.licenseprovider.getlicense(VS.80).aspx">GetLicense</a> method to get a licence. If no licence can be found, <strong>LicenseManager.Validate</strong> will throw an exception, making your component unusable.</p>
<p>Specifying the licence provider has also another usage: It&#8217;s used by Visual Studio to know whether a component is licensed or not. Indeed, as we&#8217;ve seen in the first part of this article, Visual Studio manages a <strong>licenses.licx</strong> file containing all the licensed components used in a project.</p>
<p>Microsoft provides the <a href="http://msdn2.microsoft.com/en-us/library/system.componentmodel.licfilelicenseprovider(VS.80).aspx"><span class="linkTerms">LicFileLicenseProvider</span></a> class, a ready-to-use licence provider. But if you need to implement your own logic, you have to create a new licence provider by subclassing the <strong>LicenseProvider</strong> class. That&#8217;s what we&#8217;ve done here at ILOG for our .NET products (<a href="http://www.ilog.com/products/ganttnet/">ILOG Gantt for .NET</a> and <a href="http://www.ilog.com/products/diagrammernet/">ILOG Diagrammer for .NET</a>) because we wanted to implement ILM (ILOG License Manager). Subclassing the <strong>LicenseProvider</strong> class is relatively simple, as you just need to override the <a href="http://msdn2.microsoft.com/en-us/library/system.componentmodel.licenseprovider.getlicense(VS.80).aspx">GetLicense</a> method. We&#8217;ll see later how to implement this method.</p>
<p>The <strong>LicenseProvider</strong> will be used in three different contexts:</p>
<ul>
<li>At design-time.</li>
<li>At compile-time.</li>
<li>At run-time.</li>
</ul>
<h2>Creating licences at design-time</h2>
<p>Here we assume that we&#8217;re building an application that contains licensed components using Visual Studio. The typical way to do it is to drag and drop a toolbox item onto the design surface, which results in the instantation of the component. As the licence checking is done in the component constructor, a licence has to be provided at that time. Let&#8217;s see how to handle this case in the <a href="http://msdn2.microsoft.com/en-us/library/system.componentmodel.licenseprovider.getlicense(VS.80).aspx">LicenseProvider.GetLicense</a> method through a partial implementation:</p>
<pre>public override License GetLicense(
    LicenseContext context,
    Type type,
    object instance,
    bool allowExceptions)
{
    //
    // The context parameter indicates the context
    // in which the component is used.
    //
    bool runtime = context.UsageMode == LicenseUsageMode.Runtime;                 

    if (runtime)
    {
        //
        // Will see later what to do here
        //
    }
    else
    {
        //
        // Here we are designing our application, so we need to
        // get a licence that we will store in the context.
        //                 

        //
        // We're calling the GetDesignTimeLicenseKey() method to get a licence.
        // The code for this method is not provided here, but a simple
        // implementation could be to look in the registries or in a specific
        //  file to check that a valid licence has been installed on this computer.
        // The implementation of this method depends on the licensing schema
        // you want to set up.
        //
        string licenseKey = GetDesignTimeLicenseKey(type);                 

        //
        // If no licence was found, error
        //
        if (licenseKey == null)
        {
            if (allowExceptions)
                throw new LicenseException();
            return null;
        }                

        //
        // Save the licenseKey in the context. It will be possible at runtime to
        // retrieve it.
        //
        context.SetSavedLicenseKey(type, licenseKey);                

        //
        // We create and return a new CustomLicence object using
        // the licenseKey. The code for the CustomLicense class is
        // straightforward, as it's a simple implementation of the License
        // class. It's given below.
        //
        return new CustomLicense(licenseKey);
    }
}               

class CustomLicense : License
{
    private string _key;
    public CustomLicense(string Key)
    {
        _key = key;
    }
    public override string LicenseKey
    {
        get
        {
            return _key;
        }
    }
}</pre>
<p>To sum up, the creation of a licence at design time is a 3 steps process:</p>
<ol>
<li>Get the licence key installed on the computer. It can be a licence file, or a registry key&#8230;It depends on the way you want to manage the installation of licence keys on development computers.</li>
<li>Sets the licence key into the licence context. This will make it possible to retrieve the licence key at runtime.</li>
<li>Create a <strong>License</strong> object using this licence key.</li>
</ol>
<p>Note : The <strong>License</strong> class is a .NET class that encapsulates the licence key, which is a simple string.</p>
<p>The <strong>LicenseContext</strong> used by Visual Studio and passed as the first parameter of the <a href="http://msdn2.microsoft.com/en-us/library/system.componentmodel.licenseprovider.getlicense(VS.80).aspx">GetLicense</a> method is said to be a &#8220;design-time&#8221; context, that is, a context whose <strong>UsageMode</strong> property returns <strong>LicenseUsageMode.DesignTime</strong>.</p>
<h2>Creating licences at compile-time</h2>
<p>Once the application has been designed, it needs to get compiled. As we&#8217;ve seen in the <a href="http://blogs.ilog.com/netvisu/2008/04/22/remix-08-in-paris/">first part of this article</a>, Visual Studio invokes the licence compiler to compile the <strong>licenses.licx</strong> file into an assembly resource file.</p>
<p>The licence compiler takes a .<strong>licx</strong> file as input and produces a resource file as output. It parses the .<strong>licx</strong> file and create an instance of each type found in it. The <strong>LicenseContext</strong> used by the licence compiler is a design-time context, an instance of the <a href="http://msdn2.microsoft.com/en-us/library/system.componentmodel.design.designtimelicensecontext(VS.85).aspx">DesignTimeLicenseContext</a> class. For each component created, a corresponding licence is also created and is stored in the licence context in a hash table. This hash table is then dumped it into a resource file.</p>
<p>This resource file will be used differently at run-time depending on the application type your&#8217;re creating, as explained in the <a href="http://blogs.ilog.com/netvisu/2008/04/22/remix-08-in-paris/">first part of this article</a>.</p>
<h2>Creating licences at run-time</h2>
<p>As for design-time and compile-time, licence checking will take place at run-time each time a licensed component gets instantiated. The difference is that the <strong>LicenseContext</strong> used will be a run-time licence context, that is, a context whose <strong>UsageMode</strong> property returns <strong>LicenseUsageMode.RunTime</strong>. This context will be able to retrieve the licences compiled with the licence compiler. Here is the a partial implementation of the <a href="http://msdn2.microsoft.com/en-us/library/system.componentmodel.licenseprovider.getlicense(VS.80).aspx">LicenseProvider.GetLicense</a> method:</p>
<pre>public override License GetLicense(
    LicenseContext context,
    Type type,
    object instance,
    bool allowExceptions)
{
    //
    // The context parameter indicates the context in
    // which the component is used.
    //
    bool runtime = context.UsageMode == LicenseUsageMode.Runtime;                 

    if (runtime)
    {
        //
        // At runtime, look into the context to find the licence.
        // Depending on the application type, the context may look into
        // the application resources (Windows Forms), or the
        // App_Licenses.dll assembly (Web sites)...
        //
        string licenceKey = context.GetSavedLicenseKey(type, null);                

        if (licenceKey != null)
            return new CustomLicense(licenceKey);           

        if (allowExceptions)
            throw new LicenseException();
        else
            return null;
    }
    else
    {
        //
        // Already covered in the "design-time" section
        //
    }
}</pre>
<p>The interesting part here is the call to the <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.licensecontext.getsavedlicensekey.aspx">LicenseContext.GetSavedLicenseKey</a> method. It will look into the context to see if a licence for the specified type can be found. Depending on the application type (assembly based applications, web sites, windows forms hosted in IE), the context will look in the appropriate location to find the licence.</p>
<h2>Conclusion</h2>
<p>We&#8217;ve seen in this article how the licences were created during the three phases of an application development: design-time, compile-time, run-time. Of course the code given was simpified for the purpose of this article, but you can imagine to enrich it by adding cryptography or anything that can make your licence management more secure.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ilog.com/netvisu/2008/05/22/licensing-in-net-explained-part-2/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Displaying a Microsoft Project XML file using Diagrammer for .NET, WPF and LinQ (Part 1)</title>
		<link>http://blogs.ilog.com/netvisu/2008/05/19/displaying-a-microsoft-project-xml-file-using-diagrammer-for-net-wpf-and-linq-part-1/</link>
		<comments>http://blogs.ilog.com/netvisu/2008/05/19/displaying-a-microsoft-project-xml-file-using-diagrammer-for-net-wpf-and-linq-part-1/#comments</comments>
		<pubDate>Mon, 19 May 2008 10:42:17 +0000</pubDate>
		<dc:creator>Emmanuel Tissandier</dc:creator>
		
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[Diagram]]></category>

		<category><![CDATA[Linq]]></category>

		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://blogs.ilog.com/netvisu/2008/05/19/displaying-a-microsoft-project-xml-file-using-diagrammer-for-net-wpf-and-linq-part-1/</guid>
		<description><![CDATA[Diagrammer for .NET 1.5 introduces a set of new WPF controls that can present information as a graph display made of nodes and links. In this post, I will show how you can use these controls to display the content&#8230;]]></description>
			<content:encoded><![CDATA[<p>Diagrammer for .NET 1.5 introduces a set of new WPF controls that can present information as a graph display made of nodes and links. In this post, I will show how you can use these controls to display the content of a Microsoft Project XML file. We will use .NET 3.5 and Linq to read the data and provide it to the ILOG WPF <strong>Diagram</strong> control.</p>
<p>The XML that you can export from Microsoft Project 2003 contains all the information on the project plan such as all the tasks, resources, calendars and more. Here we will only take care of the tasks and the predecessor constraints between tasks. Predecessor constraints are the constraints between tasks such as &#8220;task A starts after task B&#8221;. The graph that we will create will have nodes representing the tasks and links representing the predecessor constraints between tasks. The result will give something similar to the &#8220;Network Diagram&#8221; view of Microsoft Project that represents nicely the flow of tasks in the project plan.</p>
<p>First of all, a few words on the Microsoft Project XML format. The format defines a &lt;tasks&gt; tag that contains all the tasks, each task is represented by a &lt;task&gt; tag that contains the task information.</p>
<pre>
&lt;Project xmlns="http://schemas.microsoft.com/project"&gt;
...
&lt;Tasks&gt;
  &lt;Task&gt;
    &lt;UID&gt;Unique id of task&lt;/UID&gt;
    &lt;Name&gt;The name&lt;/Name&gt;
    &lt;Start&gt;The start date &lt;/Start&gt;
    &lt;Finish&gt;The finish date&lt;/Finish&gt;
     ...
    &lt;/Task&gt;
&lt;/Tasks&gt;
...
&lt;/Project&gt;</pre>
<p>When a task has predecessors, a &lt;PredecessorLink&gt; tag appears for each predecessor in the &lt;task&gt; tag:<br />
<code></code><code></code><code></p>
<pre>
&lt;Task&gt;
  ...
  &lt;PredecessorLink&gt;
    &lt;PredecessorUID&gt;1&lt;/PredecessorUID&gt;
    &lt;Type&gt;1&lt;/Type&gt;
  &lt;/PredecessorLink&gt;
  ...
&lt;/Task&gt;</pre>
<p>&lt;PredecessorUID&gt; corresponds to the unique id (UID tag) of the predecessor and &lt;Type&gt; gives the type of the constraint (0 for a &#8220;Finish to Finish&#8221; constraint, 1 for &#8220;Finish to Start&#8221;, 2 for &#8220;Start to Finish&#8221; and 3 for &#8220;Start to Start&#8221;).</p>
<p>That&#8217;s all we need to know to be able to read the data.</p>
<p>We now define very simple .NET classes that correspond to this structure, a class Project that represents the project, a Task and a PredecessorLink class:</p>
<pre>
public class Project
{
    public List&lt;Task&gt; Tasks { get; set; }
} 

public class PredecessorLink
{
    public int PredecessorUID { get; set; }
} 

public class Task
{
    public Project Project { get; set; }
    public int UID { get; set; }
    public string Name { get; set; }
    public DateTime Start { get; set; }
    public DateTime Finish { get; set; }
    public List&lt;PredecessorLink&gt; PredecessorLinks { get; set; }
}</pre>
<p>Thanks to Linq for XML, we can now read the data from the XML file and directly create the Project, Task and PredecessorLink instances.</p>
<pre>
XDocument document = XDocument.Load("./Engineering.xml");
Project project = new Project();
project.Tasks
      = (from task in document.Descendants("{http://schemas.microsoft.com/project}Task")
          where (int)task.Element("{http://schemas.microsoft.com/project}ID") != 0
          select new Task()
           {
               Project = project,
               UID = (int)task.Element("{http://schemas.microsoft.com/project}UID"),
               Name = (string)task.Element("{http://schemas.microsoft.com/project}Name"),
               Start = (DateTime)task.Element("{http://schemas.microsoft.com/project}Start"),
               Finish = (DateTime)task.Element("{http://schemas.microsoft.com/project}Finish"),
               PredecessorLinks =
                         (from link in task.Descendants("{http://schemas.microsoft.com/project}PredecessorLink")
                         select
                           new PredecessorLink
                           {
                               PredecessorUID = (int)link.Element("{http://schemas.microsoft.com/project}PredecessorUID")
                           }).ToList() 

              }).ToList();</pre>
<p>The LinQ code above will iterate over the &lt;Task&gt; elements in the XML document and create a Task instance, then for each Task he will create the list of PredecessorLink. Note that since the XML document defines a default namespace (http://schemas.microsoft.com/project), we need to specify this namespace when querying the document with Linq and this makes the code not really easy to read.</p>
<p>So far we have only been playing with data, we will now start to use WPF to render this information. We have a Project instance that contains a list of Task, each task containing information on its predecessors. That is almost all the information that is required to use the Diagrammer for .NET WPF Diagram control.</p>
<p>Let&#8217;s start the XAML code by using the <strong>Diagram</strong> control:</p>
<pre>
&lt;Window x:Class="CriticalPath.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ilog="http://www.ilog.com/diagrammer.net/2008"
    Title="Window1" Height="300" Width="300"&gt;
    &lt;Grid&gt;
        <strong>&lt;ilog:Diagram x:Name=&#8221;diagram&#8221;/&gt;</strong>
   &lt;/Grid&gt;
&lt;/Window&gt;</pre>
<p>We have named our control &#8220;diagram&#8221;, we can now specify the data source in the code behind:</p>
<pre>
  diagram.Source = project.Tasks;</pre>
<p>The diagram control now knows about the data source, but this information is not enough to create a graph display. At this point the result of the application is the following:<br />
<a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/05/first.png" title="first.png"><img src="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/05/first.png" alt="first.png" /></a><br />
Not so impressive&#8230;<br />
The Diagram control does not know the relation between the tasks and thus it has layout the task as a simple vertical list with no links between them. We have not defined any graphical representation for the nodes that&#8217;s why we get a simple rectangle with the name of the class (in this case this is the result of calling ToString() on the Task instances). Let&#8217;s make this look nicer.<br />
First we need to tell the Diagram that there are some relations between them. For this we use the <strong>PredecessorBinding</strong> property of the Diagram control.<br />
This <strong>PredecessorBinding</strong> property tells the control how from a Task (an item in the data source) he can find a list of predecessor Tasks (predecessor items in the data source). With this information, the Diagram control can create links between the nodes and layout the graph. So far the Task class does not have a property that returns the predecessor tasks, we only have the predecessor links. Let&#8217;s use LinQ again to create a property that returns the list of predecessor tasks:</p>
<pre>
public class Task
{
    public Project Project { get; set; }
    public int UID { get; set; }
    public string Name { get; set; }
    public DateTime Start { get; set; }
    public DateTime Finish { get; set; }
    public List&lt;PredecessorLink&gt; PredecessorLinks { get; set; }
    <strong>public List<task></task> Predecessors
    {
      get
      {
        return
          (from pred in PredecessorLinks
           join task in Project.Tasks on pred.PredecessorUID equals task.UID
           select task).ToList();
      }
    }</strong>
    public override string ToString()
    {
       return Name;
    }
}</pre>
<p>The new <strong>Predecessors</strong> property now returns the list of predecessor tasks by doing a LinQ join between the PredecessorUID in the PredecessorLink and the UID of tasks.</p>
<p>We can now change the XAML and use this new method:</p>
<pre>
    &lt;ilog:Diagram
        x:Name="diagram"
        <strong>PredecessorsBinding=&#8221;{Binding Predecessors}&#8221;</strong>&gt;</pre>
<p>Now the control knows about the relation between tasks. Note that we have also overridden the ToString method of the Task so that it returns the name of the task. Now we get the following graph that displays the constraints between tasks nicely layout:<br />
<a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/05/second.png"><img src="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/05/second1.png" /></a><br />
Now that the data is present, we can exercise our graphic designer skills using the styling and templating features of WPF to make this graph look better.<br />
The <strong>Diagram</strong> control has created instances of the <strong>Node</strong> and <strong>Link</strong> classes for nodes and links. We can then define a WPF style for these two classes:</p>
<pre>
&lt;Style TargetType="{x:Type ilog:Link}" &gt;
  &lt;Setter Property="Radius" Value="10"/&gt;
  &lt;Setter Property="Stroke" Value="#FFF0A5"/&gt;
  &lt;Setter Property="StrokeThickness" Value="2"/&gt;
  &lt;Setter Property="StartArrow"&gt;
    &lt;Setter.Value&gt;
      &lt;ilog:LinkArrow  Fill="White"  Shape="Circle"/&gt;
    &lt;/Setter.Value&gt;
  &lt;/Setter&gt;
  &lt;Setter Property="EndArrow"&gt;
    &lt;Setter.Value&gt;
      &lt;ilog:LinkArrow Fill="{x:Null}"  Shape="Open"/&gt;
    &lt;/Setter.Value&gt;
  &lt;/Setter&gt;
&lt;/Style&gt; 

&lt;Style TargetType="{x:Type ilog:Node}"&gt;
  &lt;Setter Property="Background" Value="#FFF0A5"/&gt;
  &lt;Setter Property="BorderBrush" Value="#468966"/&gt;
  &lt;Setter Property="BorderThickness" Value="1"/&gt;
&lt;/Style&gt;</pre>
<p>The style for link defines the color and thickness of links through the <strong>Stroke</strong> and <strong>StrokeThickness</strong> properties. It also defines a start and end arrow with different shapes. The style for nodes defines the colors for the background and border of the node.<br />
We are now going to display more information in the node that the simple name of the task. This is done through a WPF DataTemplate. The DataTemplate that we will specify through the <strong>NodeTemplate</strong> property of the <strong>Diagram</strong> control represents the graphical template that will be instantiated for each node. Here we will display not only the name but also the start and finish date of the task.</p>
<pre>
&lt;DataTemplate x:Key="TaskTemplate"&gt;
  &lt;Grid  Margin="5" MaxWidth="150" x:Name="grid"&gt;
    &lt;Grid.RowDefinitions&gt;
      &lt;RowDefinition/&gt;
      &lt;RowDefinition/&gt;
      &lt;RowDefinition/&gt;
    &lt;/Grid.RowDefinitions&gt;
    &lt;TextBlock
       x:Name="header" Grid.Row ="0"
       Text="{Binding Path=Name}"
       TextWrapping="WrapWithOverflow"
       Foreground="#FFB03B"
       FontWeight="Bold"/&gt;
    &lt;StackPanel x:Name="startField"  Grid.Row ="1" Orientation="Horizontal"&gt;
      &lt;TextBlock x:Name="startLabel" Text="Start:"/&gt;
      &lt;TextBlock Text="{Binding Path=Start}"/&gt;
    &lt;/StackPanel&gt;
    &lt;StackPanel x:Name="finishField" Grid.Row ="2" Orientation="Horizontal"&gt;
      &lt;TextBlock x:Name="finishLabel" Text="Finish:"/&gt;
      &lt;TextBlock Text="{Binding Path=Finish}"/&gt;
    &lt;/StackPanel&gt;
  &lt;/Grid&gt;
&lt;/DataTemplate&gt;</pre>
<p>This data template defines a grid with 3 rows, first row will display the name of the task, the second row the start date and the last row the finish date.</p>
<p>The Diagram control layouts the graph using a graph layout algorithm. ILOG Diagrammer for .NET provides a large set of graph layout algorithms that can be use to represents graph, in a Diagram the default algorithm is a Hierarchical layout algorithm. This algorithm suits perfectly for our needs because it shows nicely the flow of information in the graph. We will only modify some of the layout properties to get a nicer result. Let&#8217;s use orthogonal links and links evenly spaced on the side of nodes. We do this by specifying the layout algorithm through the <strong>GraphLayout</strong> property of the Diagram class in XAML.<br />
After adding a gradient for the background of the diagram through the Background property, the XAML is now:</p>
<pre>
&lt;ilog:Diagram
  NodeTemplate="{StaticResource TaskTemplate}"
  PredecessorsBinding="{Binding Predecessors}" x:Name="diagram"&gt; 

  &lt;!-- Background of diagram --&gt;
  &lt;ilog:Diagram.Background&gt;
    &lt;LinearGradientBrush  EndPoint="0.5,1" StartPoint="0.5,0"&gt;
      &lt;GradientStop Color="#FF555555" Offset="1"/&gt;
      &lt;GradientStop Color="#FF1C1C1C" Offset="0"/&gt;
    &lt;/LinearGradientBrush&gt;
  &lt;/ilog:Diagram.Background&gt; 

  &lt;!-- graph layout algorithm --&gt;
  &lt;ilog:Diagram.GraphLayout&gt;
    &lt;ilog:HierarchicalLayout
          LinkStyle="Orthogonal"
          ConnectorStyle="EvenlySpaced" /&gt;
  &lt;/ilog:Diagram.GraphLayout&gt;
&lt;/ilog:Diagram&gt;</pre>
<p>And the resulting graph is now much better.<br />
<a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/05/criticalpath3.png"><img src="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/05/criticalpath3.png" /></a></p>
<p>We have seen how easy it is to create a graph display using LinQ, WPF styling and templating and the Diagram control. In a second post I will show how you can go further and tailor the graph with WPF features such as data triggers and more features of the Diagram class. In particular, we will see how to display the critical path of the project plan.</p>
<p></code></p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ilog.com/netvisu/2008/05/19/displaying-a-microsoft-project-xml-file-using-diagrammer-for-net-wpf-and-linq-part-1/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Diagrammer .NET Tips and Tricks Explained Through the &#8220;UML Class Diagram&#8221; Sample - Part 2</title>
		<link>http://blogs.ilog.com/netvisu/2008/05/19/diagrammer-net-tips-and-tricks-explained-through-the-uml-class-diagram-sample-part-2/</link>
		<comments>http://blogs.ilog.com/netvisu/2008/05/19/diagrammer-net-tips-and-tricks-explained-through-the-uml-class-diagram-sample-part-2/#comments</comments>
		<pubDate>Mon, 19 May 2008 09:15:17 +0000</pubDate>
		<dc:creator>Eric Durocher</dc:creator>
		
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[Diagram]]></category>

		<guid isPermaLink="false">http://blogs.ilog.com/netvisu/2008/05/19/diagrammer-net-tips-and-tricks-explained-through-the-uml-class-diagram-sample-part-2/</guid>
		<description><![CDATA[In the <a href="http://blogs.ilog.com/netvisu/2008/04/25/diagrammer-net-tips-and-tricks-explained-through-the-uml-class-diagram-sample/">previous post</a>, we explained how to assemble built-in ILOG Diagrammer for .NET objects to build a complex UML Type symbol. The first post described how to define the appearance of the symbol, now we will define its behavior.&#8230;]]></description>
			<content:encoded><![CDATA[<p>In the <a href="http://blogs.ilog.com/netvisu/2008/04/25/diagrammer-net-tips-and-tricks-explained-through-the-uml-class-diagram-sample/">previous post</a>, we explained how to assemble built-in ILOG Diagrammer for .NET objects to build a complex UML Type symbol. The first post described how to define the appearance of the symbol, now we will define its behavior. To do this, we will need to do a bit of C# coding.</p>
<p>If you want to look at the code in Visual Studio, download the second version of the <a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/04/umlclassdiagram2.zip" title="source code (2)">source code</a> and open the UMLClassDiagram.sln solution. To see the code of the UMLType symbol, right-click the UMLType.cs item in the Solution Explorer and choose View Code.</p>
<h3>Making the Symbol Functional: Adding Properties</h3>
<p>Let&#8217;s start with an easy one: the TypeName property. We want the UML type name to be displayed in the title of our UML Type symbol. The code for the TypeName property looks like this:</p>
<pre>        [Description("The name of the UML type")]
        [Category("UML")]
        public string TypeName
        {
            get
            {
                return nameRect.Text;
            }
            set
            {
                nameRect.Text = value;
            }
        }</pre>
<p>What we did here is add a C# property to our user symbol. The property just gets/sets the Text property of the title rectangle of the symbol. This is a frequently used technique: users of your symbol do not have access to its inner elements, so you must selectively expose some of the properties of the inner elements to the outside world if you want users to be able to customize these properties.</p>
<p>Note the <code>[Description(...)]</code> and <code>[Category(...)]</code> attributes: you have probably used these attributes before if you designed .NET components. These attributes can (and should) be used on ILOG Diagrammer .NET user symbols as well.</p>
<p>To try the new property, build the solution (<em>Build &gt; Build Solution</em>), then double-click the Diagram1.cs item in the Solution Explorer. If you select a UMLType instance, you will see the new TypeName property in the property grid, and you can change its value to verify that it works correctly.</p>
<p><em>(Note: Remember to always rebuild your solution when you change a symbol: the diagrams or the other symbols that use it will be automatically updated.)</em></p>
<p>Let&#8217;s continue with the SplitterSposition property now. This property controls the vertical position of the splitter, and also the sizes of the upper and lower content areas that will contain the attributes and the methods respectively.</p>
<pre>        private float splitterPosition = 0.5f;

        [Description("The vertical position of the splitter (between 0 and 1).")]
        [Category("UML")]
        [DefaultValue(0.5f)]
        public float SplitterPosition
        {
            get
            {
                return splitterPosition;
            }
            set
            {
                if (value != splitterPosition)
                {
                    splitterPosition = value;
                    grid.Rows[0].Size = 100 * splitterPosition;
                    grid.Rows[2].Size = 100 - (100 * splitterPosition);
                }
            }
        }</pre>
<p>As you can see, the SplitterPosition property adjusts the sizes of the top and bottom rows of the GridPanel so that the splitter is at the desired position. The position is a floating-point value between 0 and 1 (0 = top, 1 = bottom). Note the <code>[DefaultValue(0.5f)]</code> attribute which makes sure that the property will not be serialized if it has its default value.</p>
<p>As before, you can try the new property: in the Diagram1 designer view, change the SplitterPosition property of a UMLType instance and see how the splitter position changes.</p>
<p>Let&#8217;s continue with something a little bit more tricky: the Attributes and Operations properties. We will explain only the Attributes property since the Operations property is almost identical. First, we have to create a simple class that describes a UML attribute.</p>
<pre>    public class UMLAttribute
    {
        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }
    }</pre>
<p>Our UML Attribute class is really simple, it has only a Name property. We can add more properties if we want (like the attribute type, scope, etc) but the Name property is enough for our explanations, so let&#8217;s keep it simple.</p>
<p>The next step is to define a collection of attributes. The collection will be a specialized subclass of the generic <code>System.Collections.ObjectModel.Collection<t></t></code> class. What we want to achieve is the following: when the user adds a UMLAttribute to the collection, a graphical item will be added in the corresponding list of our UML Type symbol. So, the collection must be able to notify its UML Type owner when an element is added to it. Here is the code of the collection.</p>
<pre>       internal class UMLAttributeCollection : Collection&lt;UMLAttribute&gt;
        {
            private UMLType owner;

            internal UMLAttributeCollection(UMLType owner)
            {
                this.owner = owner;
            }

            protected override void InsertItem(int index, UMLAttribute item)
            {
                base.InsertItem(index, item);
                owner.AttributeAdded(index, item);
            }

            protected override void RemoveItem(int index)
            {
                base.RemoveItem(index);
                owner.AttributeRemoved(index);
            }

            protected override void SetItem(int index, UMLAttribute item)
            {
                base.SetItem(index, item);
                owner.AttributeRemoved(index);
                owner.AttributeAdded(index, item);
            }

            protected override void ClearItems()
            {
                for (int i = 0; i &lt; Count; i++)
                    owner.AttributeRemoved(0);
                base.ClearItems();
            }
        }</pre>
<p>We rely on the base class <code>Collection<t></t></code> for the implementation of the collection, but we override the <code>InsertItem</code>, <code>RemoveItem</code>, <code>SetItem</code> and <code>ClearItems</code> methods to notify the &#8220;owner&#8221; of the collection, that is, the UML Type. When the content of the collection is modified, we call the <code>AttributeAdded</code> or <code>AttributeRemoved</code> method. These methods will be responsible for creating and deleting the actual graphical items displayed in our symbol:</p>
<pre>        private void AttributeAdded(int index, UMLAttribute attribute)
        {
            AttributeSymbol symbol = new AttributeSymbol();
            symbol.AttributeName = attribute.Name;
            attributesList.Items.Insert(index, symbol);
        }

        private void AttributeRemoved(int index)
        {
            UMLAttribute attribute = attributes[index];
            attributesList.Items.RemoveAt(index);
        }</pre>
<p>The graphical items that represent the UML attributes are ILOG Diagrammer .NET user symbols (the <code>AttributeSymbol</code> class). This is a really simple user symbol that contains a &#8220;blue square&#8221; icon and a text object, and that has an <code>AttributeName</code> property to change the text. We will not describe this sub-symbol in details, you can look at it by double-clicking the AttributeSymbol.cs item in the Solution Explorer (or right-click &gt; View Code to see the code).</p>
<p><em>(Note: do not confuse the UMLAttribute class with the AttributeSymbol class. The UMLAttribute class is the logical representation used to define and persist a UML attribute, whereas the AttributeSymbol class is the graphical representation of a UML attribute.)</em></p>
<p>OK, now we finally have all the pieces to create our <code>Attributes</code> property:</p>
<pre>        private UMLAttributeCollection attributes;

        public UMLType()
        {
            ...
            attributes = new UMLAttributeCollection(this);
        }

        [Description("The attributes of the UML type.")]
        [Category("UML")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public Collection&lt;UMLAttribute&gt; Attributes
        {
            get
            {
                return attributes;
            }
        }</pre>
<p>The <code>attributes</code> member variable will hold the actual collection that backs the property. This collection is created in the constructor of the UML Type class. Finally, we define the <code>Attribute</code> property. The property is read-only, it just returns the collection. To add a UML attribute, users will add items to the collection like this:</p>
<pre>            UMLAttribute attribute = new UMLAttribute();
            attribute.Name = "Attribute1";
            umlType1.Attributes.Add(attribute);</pre>
<p>One thing to note is the <code>DesignerSerializationVisibility</code> attribute. The <code>Attributes</code> property is read-only, and by default the .NET framework does not serialize read-only properties, so we need to explicitly tell the .NET framework that the property must be serialized. The <code>DesignerSerializationVisibility.Content</code> value tells the framework that the property value is created automatically by the class, and that only its content (that is, the UMLAttribute values contained in it) must be serialized/deserialized.</p>
<p>You can now try the new Attributes property in our sample diagram. Select a UML Type instance and click the &#8220;&#8230;&#8221; button in the Attributes row of the property grid. You get a dialog that lets you add, remove and modify the UMLAttribute instances of the collection. Once you click OK, the UML Type symbol is updated to show the new UML attributes.</p>
<h3><a title="A_Scrollable_List_User_Symbol" name="A_Scrollable_List_User_Symbol" class="twikiAnchorToc"></a></h3>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ilog.com/netvisu/2008/05/19/diagrammer-net-tips-and-tricks-explained-through-the-uml-class-diagram-sample-part-2/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Licensing in .NET explained - Part 1</title>
		<link>http://blogs.ilog.com/netvisu/2008/05/13/licensing-in-net-explained-part-1/</link>
		<comments>http://blogs.ilog.com/netvisu/2008/05/13/licensing-in-net-explained-part-1/#comments</comments>
		<pubDate>Tue, 13 May 2008 11:57:14 +0000</pubDate>
		<dc:creator>Robert Dupuy</dc:creator>
		
		<category><![CDATA[.NET]]></category>

		<guid isPermaLink="false">http://blogs.ilog.com/netvisu/2008/05/13/licensing-in-net-explained-part-1/</guid>
		<description><![CDATA[<a rel="attachment wp-att-36" href="http://blogs.ilog.com/netvisu/?attachment_id=36" title="licence resource in Reflector"></a>Authoring licensed .NET components is explained in several places over the web. But I was not able to find an article that would cover all the aspects of licensing in .NET. That's why I decided to write this article, and&#8230;]]></description>
			<content:encoded><![CDATA[<p><a rel="attachment wp-att-36" href="http://blogs.ilog.com/netvisu/?attachment_id=36" title="licence resource in Reflector"></a>Authoring licensed .NET components is explained in several places over the web. But I was not able to find an article that would cover all the aspects of licensing in .NET. That&#8217;s why I decided to write this article, and I hope things will be clearer after reading it.</p>
<p>First, what is the purpose of licensing ? It&#8217;s a mechanism that makes sure that only users with a valid licence can use a component. The .NET framework has a built-in licensing mechanism that makes it easy to author licensed components. From the component user point of view, it also has a great support in Visual Studio, which makes the use of licensed components easy. In this first article, we&#8217;ll focus on how to use licensed components.</p>
<h2>Using Licensed Components with Visual Studio</h2>
<p>Using licensed components inside Visual Studio is completely transparent for the user. The usual way to use components in Visual Studio is to drag and drop them from the toolbox onto a design surface: When a toolbox item is dropped onto a design surface, Visual Studio creates an instance of the component represented by the toolbox item and adds it to the designer. If the component created is a licensed component, Visual Studio also adds a <strong>licences.licx</strong> file to the Visual Studio project.</p>
<p>The <strong>licences.licx</strong> file contains the type names of the licensed components used in a Visual Studio project. Here is an example:</p>
<pre>ILOG.Views.Gantt.Windows.Forms.ActivityTable, ILOG.Gantt
ILOG.Views.Gantt.Windows.Forms.ResourceTable, ILOG.Gantt
ILOG.Views.Gantt.Windows.Forms.GanttChart, ILOG.Gantt</pre>
<p>The <strong>licences.licx</strong> file is updated each time a new licensed component is added to the designer. You can also create or edit this file by hand. You must do this for example if you don&#8217;t create the components by dragging them from the toolbox.</p>
<p>The <strong>.licx</strong> files are associated in Visual Studio with the licence compiler tool (<strong><a href="http://msdn.microsoft.com/en-us/library/ha0k3c9f(VS.80).aspx">lc.exe</a></strong>). When building your project, the license compiler is run with the licence file as parameter. Compiling the licences produces a resource file that will be used at runtime by the application. Let&#8217;s see now in details how the compiled licences are used at runtime, depending on the application type you&#8217;re building.</p>
<h3>Assembly-based Applications</h3>
<p>This category of applications regroups all the applications that are assembly based, that is, applications whose ouput produce an assembly. It contains <strong>Windows Forms</strong> applications, <strong>WPF</strong> applications, <strong>Silverlight</strong> applications, as well as class libraries. It also contains Web project applications. For these applications, the compiled licences are automatically embedded in the resources of the application assembly when the project gets compiled. For example, let&#8217;s say I have a Windows Forms application called <strong>GanttEditor.exe</strong> that&#8217;s using licensed components. After compiling the application, we can check that a licence resource has been added to the application resources. To do this, I use Reflector, my favorite .NET disassembler :</p>
<p><a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/04/licenseresource.png" title="licence resource in Reflector"></a><a rel="attachment wp-att-36" href="http://blogs.ilog.com/netvisu/?attachment_id=36" title="licence resource in Reflector"></a><a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/04/licenseresource.png" title="licence resource in Reflector"></a><a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/04/licenseresource.png" title="Licence resource in Reflector"></a><a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/04/licenseresource2.png" title="License resource in Reflector"><img src="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/04/licenseresource2.png" alt="License resource in Reflector" /></a><a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/04/licenseresource.png" title="licence resource in Reflector"></a></p>
<p>The <strong>licences.licx</strong> file has been compiled into a resource called <strong>GanttEditor.exe.licenses</strong>.</p>
<h3>Web Sites Applications</h3>
<p>In Visual Studio, a Web Site is a special project, as there&#8217;s no real project file. Instead, all the files located under the web site directory are part of the web site. When a licensed component is dropped into a <strong>Web Form</strong> designer, Visual Studio creates a <strong>licenses.licx</strong> file and adds it to the web site directory. This licence file is compiled into an assembly named <strong>App_Licenses.dll</strong>, located in the web site <strong>Bin</strong> directory. This assembly will be loaded at runtime to locate the licences. Note that you can force the generation of the <strong>App_Licenses.dll </strong>assembly by right-clicking the <strong>licenses.licx</strong> file in the solution explorer, and choosing the &#8220;Build Runtime Licenses&#8221; menu item.</p>
<h2>Using Licensed Components without Visual Studio</h2>
<p>For some reasons, you may not use Visual Studio to create your application. In this case, you&#8217;ll have to integrate the licence into your application by yourself. These are the steps to follow:</p>
<ol>
<li>Create and edit you own <strong>licenses.licx</strong> file.</li>
<li>Compile the <strong>licenses.licx</strong> file using the licence compiler (<strong>lc.exe</strong>).</li>
<li>Integrate the compiled licence file into the application.</li>
</ol>
<p>The last step depends on the type of application you&#8217;re building. For example, in a Windows Forms application, you have to put the compiled licence as an emdedded resource of the application (using the /resource option of the c# compiler if it&#8217;s a c# application). When hosting Windows Forms controls in IE, the process is different, and is described in the next section.</p>
<h3>Windows Forms controls hosted in Internet Explorer</h3>
<p>Embedding a Windows Forms control in Internet Explorer can be painful for two reasons:</p>
<ul>
<li><strong>Code Access Security</strong> : When running into Internet Explorer, the hosted control doesn&#8217;t have the same permissions as if it was run as a desktop application. Configuring the CAS is not a simple task, as well as finding the minimum permissions required by a control to work properly inside IE.</li>
<li><strong>Licence Management</strong> : You have to compile the licences by yourself.</li>
</ul>
<p>Let&#8217;s illustrate how to manage licences with a very simple example: You want to embed a <strong>GanttChart</strong> (located in the <strong>ILOG.Gantt.dll</strong> assembly) into the <strong>default.htm</strong> page. As the <strong>GanttChart</strong> is a licensed component, you&#8217;ll have to provide an entry for it in the <strong>licenses.licx</strong> file:</p>
<pre>ILOG.Views.Gantt.Windows.Forms.GanttChart, ILOG.Gantt</pre>
<p>Then, you&#8217;ll have to compile this file using the licence compiler:</p>
<pre>lc.exe /target:default.htm /complist:licenses.licx /i:ILOG.Gantt.dll </pre>
<p>the /<strong>target</strong> parameter must be the page in which the licence will be used,</p>
<p>the /<strong>complist</strong> parameter is the .licx file to compile,</p>
<p>the /<strong>i</strong> parameter indicates the assemblies needed to compile the licence.</p>
<p>The licence compiler will produce a file named <strong>default.htm.licenses</strong>. Now, we need to use this file in the HTML page as shown below: </p>
<pre>&lt;html&gt;
...
&lt;HEAD&gt;
...
&lt;LINK REL="licenses" href="default.htm.licenses" mce_href="default.htm.licenses" /&gt;
...
&lt;/HEAD&gt;
...
&lt;OBJECT id="ganttControl" height="300" width="800" classid="ILOG.Gantt.dll#ILOG.Views.Gantt.Windows.Forms.GanttChart" /&gt;
...
&lt;/html&gt;</pre>
<p>The &lt;<strong>OBJECT</strong>&gt; tag is used to insert the control in the HTML page, and the &lt;<strong>LINK</strong>&gt; tag is used to indicate where the licence can be found.</p>
<h2>Conclusion </h2>
<p>We&#8217;ve seen two different ways to use licensed components in .NET: With or without Visual Studio. When using Visual Studio, it takes care of everything. When not using it, you need to do things by yourself.</p>
<p>Now, from a developper point of view, it would be interesting to understand how the licence compiler works, and how to author licensed components. That will be the subject of a second article.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ilog.com/netvisu/2008/05/13/licensing-in-net-explained-part-1/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Diagrammer .NET Tips and Tricks Explained Through the &#8220;UML Class Diagram&#8221; Sample - Part 1</title>
		<link>http://blogs.ilog.com/netvisu/2008/04/25/diagrammer-net-tips-and-tricks-explained-through-the-uml-class-diagram-sample/</link>
		<comments>http://blogs.ilog.com/netvisu/2008/04/25/diagrammer-net-tips-and-tricks-explained-through-the-uml-class-diagram-sample/#comments</comments>
		<pubDate>Fri, 25 Apr 2008 12:45:38 +0000</pubDate>
		<dc:creator>Eric Durocher</dc:creator>
		
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[Diagram]]></category>

		<guid isPermaLink="false">http://blogs.ilog.com/netvisu/2008/04/25/diagrammer-net-tips-and-tricks-explained-through-the-uml-class-diagram-sample/</guid>
		<description><![CDATA[This is the first of a series of posts in which we will walk through the UML Class Diagram sample of ILOG Diagrammer for .NET and explain various features, tips and tricks.

The full <a href="http://svdemo02.ilog.com/DiagrammerWebDemos/UMLEditor.html">UML Class Diagram Editor sample</a> can be&#8230;]]></description>
			<content:encoded><![CDATA[<p>This is the first of a series of posts in which we will walk through the UML Class Diagram sample of ILOG Diagrammer for .NET and explain various features, tips and tricks.</p>
<p>The full <a href="http://svdemo02.ilog.com/DiagrammerWebDemos/UMLEditor.html">UML Class Diagram Editor sample</a> can be run from the ILOG web demos server as a ClickOnce application: click <a href="http://svdemo02.ilog.com/DiagrammerWebDemos/UMLEditor.html" title="UML Editor Demo">here</a>, then click the Install button. The sample is also available in the product itself with full source code. Here is a screenshot of the full sample:</p>
<p><a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/04/umlclassdiagram.png" title="The UML Class Diagram Sample"><img src="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/04/umlclassdiagram.png" alt="The UML Class Diagram Sample" /></a></p>
<p>For clarity, we describe in this post a simplified version of the sample. Here is the <a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/04/umlclassdiagram1.zip" title="source code (1)">source code</a> of this simplified version (the code will be completed as we go). You can load it in Visual Studio and follow the explanations by looking at the finished project. (<em>Note: this is a Visual Studio 2005 / ILOG Diagrammer for .NET 1.0 project, but you can load and convert it in Visual Studio 2008 and/or use it with ILOG Diagrammer for .NET 1.5 as well).</em></p>
<h3> The &#8220;UML Type&#8221; Symbol: Bulding a Complex User Symbol Easily</h3>
<p>In this first post, we will introduce the &#8220;UML Type&#8221; symbol that represents a type (a class, an enum, etc) in a UML class diagram. The UML Type symbol looks like this:</p>
<p><a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/04/umltype.png" title="The UMLType Symbol"><img src="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/04/umltype.png" alt="The UMLType Symbol" /></a></p>
<p>The symbol has a title that contains the name of the UML type. The name can be set using the TypeName property of the symbol. Below are two areas separated by a horizontal splitter. The top area contains the attributes (i.e., the properties in the C# terminology) of the class, and the bottom area contains the operations (i.e. the methods). The content of these areas is set using the Attributes and Operations properties of the symbol respectively. The values of these properties are collections, so you can add any number of attributes and operations. Scrollbars are available if the items do not all fit in the visible area.</p>
<p>In ILOG Diagrammer for .NET, you create user symbols using Visual Studio. ILOG Diagrammer for .NET is closely integrated with Visual Studio and provides an editor (the VS terminology is &#8220;Designer&#8221;) that lets you visually assemble your user symbols.</p>
<p>To examine the UMLType symbol, start Visual Studio and load the UMLClassDiagram solution. Build the solution (use <em>Build &gt; Build Solution</em>), then double-click on the UMLType.cs item  in the Solution explorer.</p>
<p>Here is a screen shot of Visual Studio with the UMLType symbol loaded in the designer:</p>
<p><a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/04/umltypevs.png" title="umltypevs.png"><img src="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/04/umltypevs.png" alt="umltypevs.png" /></a></p>
<p>Let&#8217;s zoom in to see the Document Outline (use <em>View &gt; Other Windows &gt; Document Outline</em> to show it if it is not visible). The Document Outline shows the structure of the symbol:</p>
<p><a href="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/04/umltypeoutline.png" title="umltypeoutline.png"><img src="http://blogs.ilog.com/netvisu/wp-content/uploads/2008/04/umltypeoutline.png" alt="umltypeoutline.png" /></a></p>
<p>ILOG Diagrammer for .NET user symbols are composite objects (or &#8220;containers&#8221;), that is, they are made of basic elements and other nested containers. Let us look at the elements of the UML Type symbol:</p>
<ul>
<li> dockPanel: this is the main container of the symbol. It is an instance of the DockPanel class, which is an ILOG Diagrammer for .NET      container that has a built-in layout, very similar to a Windows Forms Panel.</li>
<li> nameRect: this is the rectangle that displays the type name at the top of the symbol. Its Dock property is set to Top so that it is automatically placed at the top of the DockPanel. In ILOG Diagrammer for .NET, all graphic objects can have text displayed inside them. So, a common way to add text in a symbol is to add a Rect (rectangle) object, and to set its text. This also lets you define easily the background of the text using the Fill property of the rectangle (here we use a blue/white gradient).</li>
<li> grid: this nested container is used to layout the attributes and operations areas, and also the horizontal splitter. It is an instance of the GridPanel class, a ILOG Diagrammer for .NET container that has a layout similar to a Windows Forms TableLayoutPanel. The GridPanel makes it easy to allocate the available space in the symbol to the two variable areas: we defined three rows, the first and last rows have a height that is a percentage of the available height (initially, 50/50), and the second row (that contains the splitter) has a fixed height of 4. The GridPanel is also configured to have only one column that takes the whole horizontal space, so the children all span the entire width of the symbol. The GridPanel itself has its Dock property set to Fill, so it fill all the available space in the DockPanel (below the title rectangle).</li>
<li> attributesList and operationsList are two objects of type List. This is not a built-in ILOG Diagrammer for .NET type: the List class is itself a user symbol (also defined in the UML Class Diagram sample). The List symbol implements a scrolled list: we need one for both the attributes area and the properties area, so a good design is to create a user symbol that does this and reuse the symbol (twice in this case). The details of the List symbol will be explained in a future post.</li>
<li> separator: this is the horizontal splitter between the attributes and operations area. It is simply a Rect object, with      a gradient fill and a height of 4 pixels.</li>
</ul>
<p>Now that we looked at the graphic structure of the symbol, let&#8217;s try it. The project contains a Diagram1 class. This is the ILOG Diagrammer container object that is displayed in the main application form. Double-click the Diagram1.cs item in the Solution Explorer to edit it: it already contains a test instance of the UMLType symbol. You can create other instances of the symbol by drag-and-dropping the UMLType item from the Toolbox window. For now, we cannot do much with the symbol except moving and resizing it. See how the Attributes and Operations area resize when you resize the symbol.</p>
<p>In this first post, we explained the basic principles for building ILOG Diagrammer for .NET user symbols, and scratched the surface of some features: user symbols, panels, layout, VS integration. In the following posts, we will continue to walk through the same sample and explain more ILOG Diagrammer for .NET features as we go. The next post will be about defining the behavior to the symbol by adding C# properties in the symbol&#8217;s code.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ilog.com/netvisu/2008/04/25/diagrammer-net-tips-and-tricks-explained-through-the-uml-class-diagram-sample/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
