Extensions
Last updated
Last updated
Extensions are a powerful development tool in the Dynamo ecosystem. They allow for developers to drive custom functionality based on Dynamo interactions and logic. Extensions can be broken down into two main categories, extensions and view extensions. As the naming implies, the view extension framework allows you to extend the Dynamo UI by registering custom menu items. Regular extensions operate in a very similar fashion minus the UI. For instance, we could build an extension that logs specific information to the Dynamo console. This scenario requires no custom UI and therefore could also be accomplished using an extension.
Following the SampleViewExtension example from the DynamoSamples Github repository, we will walk through the steps necessary to create a simple modeless window that displays the active nodes in the graph in real-time. A view extension requires that we create a UI for the window and bind values to a view model.
The view extension window developed following the SampleViewExtension example in the Github repository.
Though we will build the example from the ground up, you can also download and build the DynamoSamples repository to serve as a reference.
The DynamoSamples repository: https://github.com/DynamoDS/DynamoSamples
This walk-through will be specifically referencing the project named SampleViewExtension found in
DynamoSamples/src/
.
A view extension has three essential parts:
An assembly containing a class that implements IViewExtension
as well as a class that creates a view model
An .xml
file that tells Dynamo where it should look for this assembly at runtime, and the type of extension
An .xaml
file that binds data to the graphic display and determines the window's appearance
1. Create the project structure
Start by creating a new Class Library
project named SampleViewExtension
.
Create a new project by selecting
File > New > Project
Select
Class Library
Name the project
SampleViewExtension
Select
Ok
In this project, we will need two classes. One class will implement IViewExtension
and another that will implement NotificationObject.
IViewExtension
will contain all the information about how our extension will be deployed, loaded, referenced, and disposed. NotificationObject
will provide notifications for changes in Dynamo and IDisposable
When a change occurs the count will update accordingly.
A class file named
SampleViewExtension.cs
that will implementIViewExtension
A class file named
SampleWindowViewMode.cs
that will implementNotificationObject
To use IViewExtension
, we will need the WpfUILibrary NuGet package. Installing this package will automatically install the Core, Services, and ZeroTouchLibrary packages.
Select the WpfUILibrary
Select
Install
to install all dependent packages
2. Implement the IViewExtension class
From the IViewExtension
class we will determine what happens when Dynamo starts up, when the extension is loaded, and when Dynamo shuts down. In the SampleViewExtension.cs
class file, add the following code:
The SampleViewExtension
class creates a clickable menu item to open the window and connects it to the view model and window.
public class SampleViewExtension : IViewExtension
SampleViewExtension
inherits from the IViewExtension
interface provides everything we need to create the menu item.
sampleMenuItem = new MenuItem { Header = "Show View Extension Sample Window" };
creates a MenuItem and adds it to the View
menu.
The menu item
sampleMenuItem.Click += (sender, args)
triggers an event that will open a new window when the menu item is clicked
MainGrid = { DataContext = viewModel }
sets the data context for the main grid in the window, referring to Main Grid
in the .xaml
file we will create
Owner = p.DynamoWindow
sets the owner of our pop-out window to Dynamo. This means the new window is dependent on Dynamo so actions such as minimizing, maximizing, and restoring Dynamo will cause the new window to follow this same behavior
window.Show();
displays the window the additional window properties have been set
3. Implementing the view model
Now that we have established some of the window's basic parameters, we will add the logic for responding to various Dynamo related events and instruct the UI to update based on these events. Copy the following code into the SampleWindowViewModel.cs
class file:
This implementation of the view model class listens to the CurrentWorkspaceModel
and triggers an event when a node is added or removed from the workspace. This raises a property change that notifies the UI or bound elements that the data has changed and needs to be updated. The ActiveNodeTypes
getter is called which internally calls an additional helper function getNodeTypes()
. This function iterates through all the active nodes on the canvas, populate a string containing the names of these nodes, and returns this string to our binding in the .xaml file to be displayed in our pop-out window.
With the core logic of the extension defined, we will now specify the appearance details of the window with an .xaml
file. All we need is a simple window that will display the string via the ActiveNodeTypes
property binding in theTextBlock
Text
.
Right-click on the project and select
Add > New Item...
Select the User Control template which we will alter to create a window
Name the new file
SampleWindow.xaml
Select
Add
In the window .xaml
code, we will need to bind SelectedNodesText
to a text block. Add the following code to SampleWindow.xaml
:
Text="{Binding ActiveNodeTypes}"
binds to the property value of ActiveNodeTypes
in SampleWindowViewModel.cs
to the TextBlock
Text
value in the window.
We will now initialize the sample window in the .xaml C# backing file SampleWindow.xaml.cs
. Add the following code to SampleWindow.xaml
:
The view extension is now ready to be built and added to Dynamo. Dynamo requires an xml
file in order to register our output .dll
as an extension.
Right-click on the project and select
Add > New Item...
Select XML file
Name the file
SampleViewExtension_ViewExtensionDefinition.xml
Select
Add
The file name follows the Dynamo standard for referencing an extension assembly like so: "extensionName"_ViewExtensionDefinition.xml
In the xml
file, add the following code to tell Dynamo where to look for the extension assembly:
In this example, we built the assembly to the default Visual Studio project folder. Replace the <AssemblyPath>...</AssemblyPath>
target with the location of the assembly.
The last step is to copy the SampleViewExtension_ViewExtensionDefinition.xml
file into Dynamo's view extensions folder located in the Dynamo Core installation directory C:\Program Files\Dynamo\Dynamo Core\1.3\viewExtensions
. It is important to note that there are separate folders for extensions
and viewExtensions
. Placing the xml
file in the incorrect folder may cause failure to properly load at runtime.
The
.xml
file we copied into Dynamo's view extensions folder
This is a basic introduction to view extensions. For a more sophisticated case study see the DynaShape package, an open source project on Github. The package uses a view extension that enables live editing in the Dynamo model view.
A package installer for DynaShape can be downloaded from the Dynamo Forum: https://forum.dynamobim.com/t/dynashape-published/11666
The source code can be cloned from Github: https://github.com/LongNguyenP/DynaShape