Implement click and double-click events in the Diagram for ASP.NET

Applies to: Nevron Diagram for .NET

How to implement click and double-click events in the Diagram for ASP.NET?

The following example creates a simple diagram. By using the Nevron AJAX tools, we have set click and double-click events with URL redirection:
- The shapes can be selected and colored with a single mouse click;
- Browser redirection on double mouse click;


1. Create a new ASP.NET application.
2. If the current page view is Source, switch to Design.
3. Drag and drop the NDrawingView on the page.
4. Open the solution explorer and make sure to add references to the following Nevron assemblies: Nevron.Diagram.dll; Nevron.Diagram.Shapes.dll; Nevron.Diagram.WebForm.dll; Nevron.Presentation.dll; Nevron.System.dll; and Nevron.UI.WebForm.Controls.dll;
5. From the Solution explorer select all Nevron references and set Copy Local property to True.
6. From the Solution explorer open the Web.config and make sure the following configuration exists in your web.config file:

<?xml version="1.0"?>
 
<configuration>
    <system.web>
      <httpHandlers>
        <add path="NevronDiagram.axd" verb="*" type="Nevron.Diagram.WebForm.NDiagramImageResourceHandler"
          validate="false" />
        <add path="NevronScriptManager.axd" verb="*" type="Nevron.UI.WebForm.Controls.NevronScriptManager"
          validate="false" />
      </httpHandlers>
    </system.web>
 
    <system.webServer>
        <handlers>
            <add name="NevronDiagram" preCondition="integratedMode" verb="*"
                path="NevronDiagram.axd" type="Nevron.Diagram.WebForm.NDiagramImageResourceHandler" />
            <add name="NevronScriptManager" preCondition="integratedMode"
                verb="*" path="NevronScriptManager.axd" type="Nevron.UI.WebForm.Controls.NevronScriptManager" />
        </handlers>
    </system.webServer>
 
</configuration>

7. From the Solution explorer open the Default.aspx Source and make sure the following configuration exists:

C# Project:
<%@ Page Title="Home Page" Language="C#" AutoEventWireup="true"
    CodeBehind="Default.aspx.cs" Inherits="DiagramMouseEvents._Default" %>
 
<%@ Register assembly="Nevron.Diagram.WebForm" namespace="Nevron.Diagram.WebForm" tagprefix="ndwc" %>
 
<form id="form1" runat="server">
<ndwc:NDrawingView ID="NDrawingView1" runat="server" Height="300px"
    Width="450px" AjaxEnabled="True" AsyncCallbackTimeout="10000"
    OnQueryAjaxTools="NDrawingView1_QueryAjaxTools"
    OnAsyncClick="NDrawingView1_AsyncClick"
    OnAsyncDoubleClick="NDrawingView1_AsyncDoubleClick"
    OnAsyncQueryCommandResult="NDrawingView1_AsyncQueryCommandResult" />
</form>
 
<!-- Custom JavaScript placeholder START -->
<script type="text/javascript" language="javascript">
    // Called when an async command has completed successfully.
    // Event handling code is provided for desired commands only.
    // This handler is attached to the AsyncCallbackSucceeded event at the end of the JavaScript block.
    function CallbackSucceeded(self, result, context) {
        switch (context.command) {
            case 'mouseDoubleClick':
                var transport = new NAjaxXmlTransport();
                transport.Deserialize(result);
 
                var url = transport.DataSections["url"];
                if (typeof url !== "undefined") {
                    window.location = url.Data;
                }
                break;
        }
    }
 
    NEventSinkService.AsyncCallbackSucceeded.Subscribe(null, CallbackSucceeded);
</script>
<!-- Custom JavaScript placeholder END -->

VB.NET Project:
<%@ Page Title="Home Page" Language="vb" AutoEventWireup="true"
    CodeBehind="Default.aspx.vb" Inherits="DiagramMouseEvents._Default" %>
 
<%@ Register assembly="Nevron.Diagram.WebForm" namespace="Nevron.Diagram.WebForm" tagprefix="ndwc" %>
 
<form id="form1" runat="server">
<ndwc:NDrawingView ID="NDrawingView1" runat="server" Height="300px"
    Width="450px" AjaxEnabled="True" AsyncCallbackTimeout="10000"
    OnQueryAjaxTools="NDrawingView1_QueryAjaxTools"
    OnAsyncClick="NDrawingView1_AsyncClick"
    OnAsyncDoubleClick="NDrawingView1_AsyncDoubleClick"
    OnAsyncQueryCommandResult="NDrawingView1_AsyncQueryCommandResult" />
</form>
 
<!-- Custom JavaScript placeholder START -->
<script type="text/javascript" language="javascript">
    // Called when an async command has completed successfully.
    // Event handling code is provided for desired commands only.
    // This handler is attached to the AsyncCallbackSucceeded event at the end of the JavaScript block.
    function CallbackSucceeded(self, result, context) {
        switch (context.command) {
            case 'mouseDoubleClick':
                var transport = new NAjaxXmlTransport();
                transport.Deserialize(result);
 
                var url = transport.DataSections["url"];
                if (typeof url !== "undefined") {
                    window.location = url.Data;
                }
                break;
        }
    }
 
    NEventSinkService.AsyncCallbackSucceeded.Subscribe(null, CallbackSucceeded);
</script>
<!-- Custom JavaScript placeholder END -->

8. From the Solution explorer right click on Default.aspx and select "View code".
9. Use the following code example to programmatically create the diagram:

[C#]
using System;
using System.Drawing;
 
using Nevron.Diagram;
using Nevron.Diagram.Filters;
using Nevron.Diagram.Layout;
using Nevron.Diagram.Shapes;
using Nevron.Diagram.WebForm;
using Nevron.Dom;
using Nevron.GraphicsCore;
using Nevron.UI.WebForm.Controls;
...
#region Page Entry Point
 
protected void Page_Load(object sender, EventArgs e)
{
    if (NDrawingView1.RequiresInitialization)
    {
        NDrawingView1.ViewLayout = CanvasLayout.Fit;
 
        NDrawingView1.Document.BeginInit();
        CreateDiagram();
        NDrawingView1.Document.SizeToContent();
        NDrawingView1.Document.EndInit();
    }
}
 
#endregion
 
#region Diagram Creation
 
private void CreateDiagram()
{
    NDrawingDocument document = NDrawingView1.Document;
 
    // Add style sheets
    NStyleSheet clickedSheet = new NStyleSheet(ClickedStyleSheetName);
    NStyle.SetFillStyle(clickedSheet, new NColorFillStyle(Color.Orange));
    NStyle.SetStrokeStyle(clickedSheet, new NStrokeStyle(new NLength(1.75f, NGraphicsUnit.Point), Color.Red));
    document.StyleSheets.AddChild(clickedSheet);
 
    // Create a shape factory
    NBasicShapesFactory factory = new NBasicShapesFactory();
    factory.DefaultSize = new NSizeF(100, 60);
 
    // Create some shapes
    NShape nevronVision = factory.CreateShape(BasicShapes.RoundedRectangle);
    nevronVision.Text = "Nevron .NET Vision";
    document.ActiveLayer.AddChild(nevronVision);
 
    NShape nevronChart = factory.CreateShape(BasicShapes.RoundedRectangle);
    nevronChart.Text = "Nevron Chart for .NET";
    document.ActiveLayer.AddChild(nevronChart);
 
    NShape nevronDiagram = factory.CreateShape(BasicShapes.RoundedRectangle);
    nevronDiagram.Text = "Nevron Diagram for .NET";
    document.ActiveLayer.AddChild(nevronDiagram);
 
    NShape nevronUI = factory.CreateShape(BasicShapes.RoundedRectangle);
    nevronUI.Text = "Nevron UI for .NET";
    document.ActiveLayer.AddChild(nevronUI);
 
    // Connect the shapes
    Connect(nevronVision, nevronChart);
    Connect(nevronVision, nevronDiagram);
    Connect(nevronVision, nevronUI);
 
    // Layout the shapes
    NLayeredTreeLayout layout = new NLayeredTreeLayout();
    NNodeList shapes = document.ActiveLayer.Children(NFilters.Shape2D);
    layout.Direction = LayoutDirection.TopToBottom;
    layout.OrthogonalEdgeRouting = true;
    layout.BusAlignment = 0.5f;
    layout.BusBetweenLayers = true;
    layout.CompactBreadth = true;
    layout.LayerAlignment = RelativeAlignment.Center;
    layout.LayerSpacing = 30;
    layout.VertexSpacing = 30;
    layout.Layout(shapes, new NDrawingLayoutContext(document));
}
private void Connect(NShape shape1, NShape shape2)
{
 
    NRoutableConnector connector = new NRoutableConnector();
    NDrawingView1.Document.ActiveLayer.AddChild(connector);
    connector.StyleSheetName = "Connectors";
    connector.FromShape = shape1;
    connector.ToShape = shape2;
}
 
#endregion
 
#region Event Handlers
 
protected void NDrawingView1_QueryAjaxTools(object sender, EventArgs e)
{
    //  configure the client side tools
    NDrawingView1.AjaxTools.Add(new NAjaxMouseClickCallbackTool(true));
    NDrawingView1.AjaxTools.Add(new NAjaxMouseDoubleClickCallbackTool(true));
}
 
protected void NDrawingView1_AsyncClick(object sender, EventArgs e)
{
    NDrawingView view = (NDrawingView)sender;
    NCallbackMouseEventArgs args = e as NCallbackMouseEventArgs;
 
    // Get all shapes under the mouse cursor
    NNodeList nodes = view.HitTest(args);
    NNodeList shapes = nodes.Filter(NFilters.Shape2D);
    if (shapes.Count == 0)
    {
        NDrawingView1.Document.Tag = null;
        return;
    }
 
    // Consider the first shape as clicked
    NShape shape = (NShape)shapes[0];
 
    // Change the shape's style sheet
    shape.StyleSheetName = String.IsNullOrEmpty(shape.StyleSheetName) ? ClickedStyleSheetName : String.Empty;
}
protected void NDrawingView1_AsyncDoubleClick(object sender, EventArgs e)
{
    NDrawingView view = (NDrawingView)sender;
    NCallbackMouseEventArgs args = e as NCallbackMouseEventArgs;
 
    // Get all shapes under the mouse cursor
    NNodeList nodes = view.HitTest(args);
    NNodeList shapes = nodes.Filter(NFilters.Shape2D);
    if (shapes.Count == 0)
    {
        NDrawingView1.Document.Tag = null;
        return;
    }
 
    // Consider the first shape as clicked
    NShape shape = (NShape)shapes[0];
 
    // Remember the clicked shape in the document's Tag
    NDrawingView1.Document.Tag = shape;
}
protected void NDrawingView1_AsyncQueryCommandResult(object sender, EventArgs e)
{
    NDrawingView view = (NDrawingView)sender;
    NCallbackQueryCommandResultArgs args = e as NCallbackQueryCommandResultArgs;
    NCallbackCommand command = args.Command;
    NAjaxXmlTransportBuilder resultBuilder = args.ResultBuilder;
 
    switch (command.Name)
    {
        case "mouseDoubleClick":
            // Build a custom response data section
            NShape shape = NDrawingView1.Document.Tag as NShape;
            if (shape != null)
            {
                NAjaxXmlDataSection section = new NAjaxXmlDataSection(UrlDataSectionName);
                section.Data = shape.Tag.ToString();
                resultBuilder.AddDataSection(section);
            }
            break;
    }
}
 
#endregion
 
#region Constants
 
private const string ClickedStyleSheetName = "Clicked";
private const string UrlDataSectionName = "url";
 
#endregion

[VB.NET]
Imports Microsoft.VisualBasic
Imports System
Imports System.Drawing
 
Imports Nevron.Diagram
Imports Nevron.Diagram.Filters
Imports Nevron.Diagram.Layout
Imports Nevron.Diagram.Shapes
Imports Nevron.Diagram.WebForm
Imports Nevron.Dom
Imports Nevron.GraphicsCore
Imports Nevron.UI.WebForm.Controls
...
#Region "Page Entry Point"
 
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
    If NDrawingView1.RequiresInitialization Then
        NDrawingView1.ViewLayout = CanvasLayout.Fit
 
        NDrawingView1.Document.BeginInit()
        CreateDiagram()
        NDrawingView1.Document.SizeToContent()
        NDrawingView1.Document.EndInit()
    End If
End Sub
 
#End Region
 
#Region "Diagram Creation"
 
Private Sub CreateDiagram()
    Dim document As NDrawingDocument = NDrawingView1.Document
 
    ' Add style sheets
    Dim clickedSheet As NStyleSheet = New NStyleSheet(ClickedStyleSheetName)
    NStyle.SetFillStyle(clickedSheet, New NColorFillStyle(Color.Orange))
    NStyle.SetStrokeStyle(clickedSheet, New NStrokeStyle(New NLength(1.75f, NGraphicsUnit.Point), Color.Red))
    document.StyleSheets.AddChild(clickedSheet)
 
    ' Create a shape factory
    Dim factory As NBasicShapesFactory = New NBasicShapesFactory()
    factory.DefaultSize = New NSizeF(100, 60)
 
    ' Create some shapes
    Dim nevronVision As NShape = factory.CreateShape(BasicShapes.RoundedRectangle)
    nevronVision.Text = "Nevron .NET Vision"
    document.ActiveLayer.AddChild(nevronVision)
 
    Dim nevronChart As NShape = factory.CreateShape(BasicShapes.RoundedRectangle)
    nevronChart.Text = "Nevron Chart for .NET"
    document.ActiveLayer.AddChild(nevronChart)
 
    Dim nevronDiagram As NShape = factory.CreateShape(BasicShapes.RoundedRectangle)
    nevronDiagram.Text = "Nevron Diagram for .NET"
    document.ActiveLayer.AddChild(nevronDiagram)
 
    Dim nevronUI As NShape = factory.CreateShape(BasicShapes.RoundedRectangle)
    nevronUI.Text = "Nevron UI for .NET"
    document.ActiveLayer.AddChild(nevronUI)
 
    ' Connect the shapes
    Connect(nevronVision, nevronChart)
    Connect(nevronVision, nevronDiagram)
    Connect(nevronVision, nevronUI)
 
    ' Layout the shapes
    Dim layout As NLayeredTreeLayout = New NLayeredTreeLayout()
    Dim shapes As NNodeList = document.ActiveLayer.Children(NFilters.Shape2D)
    layout.Direction = LayoutDirection.TopToBottom
    layout.OrthogonalEdgeRouting = True
    layout.BusAlignment = 0.5f
    layout.BusBetweenLayers = True
    layout.CompactBreadth = True
    layout.LayerAlignment = RelativeAlignment.Center
    layout.LayerSpacing = 30
    layout.VertexSpacing = 30
    layout.Layout(shapes, New NDrawingLayoutContext(document))
End Sub
Private Sub Connect(ByVal shape1 As NShape, ByVal shape2 As NShape)
 
    Dim connector As NRoutableConnector = New NRoutableConnector()
    NDrawingView1.Document.ActiveLayer.AddChild(connector)
    connector.StyleSheetName = "Connectors"
    connector.FromShape = shape1
    connector.ToShape = shape2
End Sub
 
#End Region
 
#Region "Event Handlers"
 
Protected Sub NDrawingView1_QueryAjaxTools(ByVal sender As Object, ByVal e As EventArgs)
    '   configure the client side tools
    NDrawingView1.AjaxTools.Add(New NAjaxMouseClickCallbackTool(True))
    NDrawingView1.AjaxTools.Add(New NAjaxMouseDoubleClickCallbackTool(True))
End Sub
 
Protected Sub NDrawingView1_AsyncClick(ByVal sender As Object, ByVal e As EventArgs)
    Dim view As NDrawingView = CType(sender, NDrawingView)
    Dim args As NCallbackMouseEventArgs = TryCast(e, NCallbackMouseEventArgs)
 
    ' Get all shapes under the mouse cursor
    Dim nodes As NNodeList = view.HitTest(args)
    Dim shapes As NNodeList = nodes.Filter(NFilters.Shape2D)
    If shapes.Count = 0 Then
        NDrawingView1.Document.Tag = Nothing
        Return
    End If
 
    ' Consider the first shape as clicked
    Dim shape As NShape = CType(shapes(0), NShape)
 
    ' Change the shape's style sheet
    If String.IsNullOrEmpty(shape.StyleSheetName) Then
        shape.StyleSheetName = ClickedStyleSheetName
    Else
        shape.StyleSheetName = String.Empty
    End If
End Sub
Protected Sub NDrawingView1_AsyncDoubleClick(ByVal sender As Object, ByVal e As EventArgs)
    Dim view As NDrawingView = CType(sender, NDrawingView)
    Dim args As NCallbackMouseEventArgs = TryCast(e, NCallbackMouseEventArgs)
 
    ' Get all shapes under the mouse cursor
    Dim nodes As NNodeList = view.HitTest(args)
    Dim shapes As NNodeList = nodes.Filter(NFilters.Shape2D)
    If shapes.Count = 0 Then
        NDrawingView1.Document.Tag = Nothing
        Return
    End If
 
    ' Consider the first shape as clicked
    Dim shape As NShape = CType(shapes(0), NShape)
 
    ' Remember the clicked shape in the document's Tag
    NDrawingView1.Document.Tag = shape
End Sub
Protected Sub NDrawingView1_AsyncQueryCommandResult(ByVal sender As Object, ByVal e As EventArgs)
    Dim view As NDrawingView = CType(sender, NDrawingView)
    Dim args As NCallbackQueryCommandResultArgs = TryCast(e, NCallbackQueryCommandResultArgs)
    Dim command As NCallbackCommand = args.Command
    Dim resultBuilder As NAjaxXmlTransportBuilder = args.ResultBuilder
 
    Select Case command.Name
        Case "mouseDoubleClick"
            ' Build a custom response data section
            Dim shape As NShape = TryCast(NDrawingView1.Document.Tag, NShape)
            If Not shape Is Nothing Then
                Dim section As NAjaxXmlDataSection = New NAjaxXmlDataSection(UrlDataSectionName)
                section.Data = shape.Tag.ToString()
                resultBuilder.AddDataSection(section)
            End If
    End Select
End Sub
 
#End Region
 
#Region "Constants"
 
Private Const ClickedStyleSheetName As String = "Clicked"
Private Const UrlDataSectionName As String = "url"
 
#End Region

Article ID: 209, Created On: 3/5/2012, Modified: 3/5/2012

Comments (1)

Erik Jungnickel

Hello, I always get the error "NDiagramCallbackService is undefined".
Any hints? In the project I am working on I can not use the <form> tag and also not use this Inherits="DiagramMouseEvents._Default". Could that be the cause of the error message?

5/22/2012 at 1:58 PM