What is the event I need to subscribe so that it fires when user adds Nodes to canvas - C#

Hey guys,

I need to know what is the event I must subscribe that fires when user inserts dynamo node in canvas.

Do you have some examples?

I have done this in grasshopper (similar to dynamo) like this:

  void DocumentAdded(GH_DocumentServer documentServer, GH_Document document)
  {
     GH_Document grasshopperDocument = document;
     grasshopperDocument.ObjectsAdded -= addSourceChangeHandlerToNewlyAddedObjects;
     grasshopperDocument.ObjectsAdded += addSourceChangeHandlerToNewlyAddedObjects;
  }

  void addSourceChangeHandlerToNewlyAddedObjects(Object sender, GH_DocObjectEventArgs e)
  {
     foreach (IGH_DocumentObject ghDocumentObject in e.Objects)
     {
        GH_Document grasshopperDocument = ghDocumentObject.OnPingDocument();

        var grasshopperComponentsUsageCollector = new StatisticsCollector();
        grasshopperComponentsUsageCollector.Start(
           "Grasshopper-DevTools", 
           ghDocumentObject.Name, 
           ghDocumentObject.Category, 
           ghDocumentObject.SubCategory, 
           ghDocumentObject.Description,
           grasshopperDocument.DisplayName,
           grasshopperDocument.FilePath
           );
        grasshopperComponentsUsageCollector.End();
     }
  }

The event to subscribe was Grasshopper.Instances.DocumentServer.DocumentAdded event

1 Like

@Michael_Kirschner2, @Racel_Williams, @Dimitar_Venkov, @Radu_Gidei?

I cannot help you on how to do it but you maybe able to find something from either of the following

Node developer info: http://dynamobim.org/developer/

Samples: https://github.com/DynamoDS/DynamoSamples

I think this is handled by inheriting from NotificationObject. It is demonstrated in the samples in the link above. Try by building that out first and tinkering.

Here is a direct link to the ViewModel from the samples that shows how this works…

Everytime a new Node is added to the NodeModel the ViewModel registers that this has been changed and gets the nodes from the NodeModel which is then displayed in the WPF view.

you can watch nodeAdded on the workspace.

3 Likes

Hey guys,

I solved the previous problem.

Now I register also the CurrentWorkspaceChanged event and then inside that event I register then the NodeAdded.

It works well.

Still 2 questions for you experts:
Question 1:
Check my Dispose method below, I am disposing the CurrentWorkspaceChanged and then the multiple NodeAdded events to all the workspace models.
Is htis correct?
Do I even need to dispose of those? Doesnt Dynamo handle that for me?

Question 2:
In the Loaded function I need to call by hand the CurrentWorkspaceChanged event because it seems that at that time the first workspace is already loaded so if I dont do this hack it wouldnt work fine.
Is there a place where the workspace is “still loading” where I could register the CurrentWorkspaceChanged event so that i dont need this ugly extra codeline :slight_smile:

   public class SwecoNodeUsageStatisticsExtension : IViewExtension
   {
      private ReadyParams _readyParams;
      private string _dynamoVersion;

      public void Dispose()
      {
         _readyParams.CurrentWorkspaceChanged -= CurrentWorkspaceChanged;

         foreach (var workspaceModel in _readyParams.WorkspaceModels)
         {
            workspaceModel.NodeAdded -= CurrentWorkspaceModel_NodesChanged;
         }
      }

      public void Startup(ViewStartupParams p)
      {
         var version = p.DynamoVersion;
         _dynamoVersion = version.Major + "." + version.Minor + "."+ version.Build;
      }

      public void Loaded(ViewLoadedParams p)
      {
         _readyParams = p;

         _readyParams.CurrentWorkspaceChanged += CurrentWorkspaceChanged;

         // If this is not here if I create a new model in beggining events dont trigger
         CurrentWorkspaceChanged(_readyParams.CurrentWorkspaceModel);
      }

      private void CurrentWorkspaceChanged(IWorkspaceModel iWorkspaceModel)
      {
         iWorkspaceModel.NodeAdded += CurrentWorkspaceModel_NodesChanged;
      }

      private void CurrentWorkspaceModel_NodesChanged(NodeModel obj)
      {
         var nodesUsageCollector = new StatisticsCollector();
         nodesUsageCollector.Start(
            "Dynamo-DevTools",
            obj.NickName,
            obj.Category,
            obj.Category,
            obj.Description,
            "",
            "",
            _dynamoVersion,
            _readyParams.CurrentWorkspaceModel.Name.Replace("*", ""),
            _readyParams.CurrentWorkspaceModel.FileName
         );
         nodesUsageCollector.End();
      }

      public void Shutdown()
      {
      }

      public string UniqueId
      {
         get { return Guid.NewGuid().ToString(); }
      }

      public string Name
      {
         get { return "SwecoNodeUsageStatisticsExtension"; }
      }

   }

Hey guys,

I kinda managed this but there is still some problem I need your help to solve.

Now the event is registered nicely when I open Dynamo and create a new project, however when I open existing project it stops working, any suggestions?

Should I register the events in Different place? Like a place where the NodeChanged event is triggered in all the workspaces ?

Current code below

   public class SwecoNodeUsageStatisticsExtension : IViewExtension
   {
      private ReadyParams _readyParams;
      private string _dynamoVersion;

      public void Dispose()
      {
         _readyParams.CurrentWorkspaceChanged -= CurrentWorkspaceChanged;

         foreach (var workspaceModel in _readyParams.WorkspaceModels)
         {
            workspaceModel.NodeAdded -= CurrentWorkspaceModel_NodesChanged;
         }
      }

      public void Startup(ViewStartupParams p)
      {
         var version = p.DynamoVersion;
         _dynamoVersion = version.Major + "." + version.Minor + "."+ version.Build;
      }

      public void Loaded(ViewLoadedParams p)
      {
         _readyParams = p;

         _readyParams.CurrentWorkspaceChanged += CurrentWorkspaceChanged;

         // If this is not here if I create a new model in beggining events dont trigger
         CurrentWorkspaceChanged(_readyParams.CurrentWorkspaceModel);
      }

      private void CurrentWorkspaceChanged(IWorkspaceModel iWorkspaceModel)
      {
         iWorkspaceModel.NodeAdded += CurrentWorkspaceModel_NodesChanged;
      }

      private void CurrentWorkspaceModel_NodesChanged(NodeModel obj)
      {
         var nodesUsageCollector = new StatisticsCollector();
         nodesUsageCollector.Start(
            "Dynamo-DevTools",
            obj.NickName,
            obj.Category,
            obj.Category,
            obj.Description,
            "",
            "",
            _dynamoVersion,
            _readyParams.CurrentWorkspaceModel.Name.Replace("*", ""),
            _readyParams.CurrentWorkspaceModel.FileName
         );
         nodesUsageCollector.End();
      }

      public void Shutdown()
      {
      }

      public string UniqueId
      {
         get { return Guid.NewGuid().ToString(); }
      }

      public string Name
      {
         get { return "SwecoNodeUsageStatisticsExtension"; }
      }

   }

Hey guys,

I solved the problem.

Do I need to dispose the events in the Dispose method or will Dynamo do that for me automatically?
If it is needed, should it be done like that?

Current code below

   public class SwecoNodeUsageStatisticsExtension : IViewExtension
   {
      private ReadyParams _readyParams;
      private string _dynamoVersion;

      public void Dispose()
      {
         _readyParams.CurrentWorkspaceChanged -= CurrentWorkspaceChanged;

         foreach (var workspaceModel in _readyParams.WorkspaceModels)
         {
            workspaceModel.NodeAdded -= CurrentWorkspaceModel_NodesChanged;
         }
      }

      public void Startup(ViewStartupParams p)
      {
         var version = p.DynamoVersion;
         _dynamoVersion = version.Major + "." + version.Minor + "."+ version.Build;
      }

      public void Loaded(ViewLoadedParams p)
      {
         _readyParams = p;

         _readyParams.CurrentWorkspaceChanged += CurrentWorkspaceChanged;

         // If this is not here if I create a new model in beggining events dont trigger
         CurrentWorkspaceChanged(_readyParams.CurrentWorkspaceModel);
      }

      private void CurrentWorkspaceChanged(IWorkspaceModel iWorkspaceModel)
      {
         iWorkspaceModel.NodeAdded += CurrentWorkspaceModel_NodesChanged;
      }

      private void CurrentWorkspaceModel_NodesChanged(NodeModel obj)
      {
         var nodesUsageCollector = new StatisticsCollector();
         nodesUsageCollector.Start(
            "Dynamo-DevTools",
            obj.NickName,
            obj.Category,
            obj.Category,
            obj.Description,
            "",
            "",
            _dynamoVersion,
            _readyParams.CurrentWorkspaceModel.Name.Replace("*", ""),
            _readyParams.CurrentWorkspaceModel.FileName
         );
         nodesUsageCollector.End();
      }

      public void Shutdown()
      {
      }

      public string UniqueId
      {
         get { return Guid.NewGuid().ToString(); }
      }

      public string Name
      {
         get { return "SwecoNodeUsageStatisticsExtension"; }
      }

   }
1 Like

Looking forward to see the statistics, @Ricardo.Farinha :slight_smile:

Hey Jostein / Ricardo, wanna ping me an email/DM ? i’m working on a platform that does pretty much what @Ricardo.Farinha seems to be implementing below, would love to chat !

Hey Radu,

Sure, please send me your email, I send you a meeting invitation.

We could have a web meeting in August perhaps.

  • Ricardo