Estensioni

Le estensioni sono un potente strumento di sviluppo nell'ecosistema di Dynamo. Consentono agli sviluppatori di gestire funzionalità personalizzate basate sulle interazioni e sula logica di Dynamo. Le estensioni possono essere suddivise in due categorie principali, ovvero estensioni ed estensioni delle viste. Come implica la denominazione, la framework dell'estensione della vista consente di estendere l'interfaccia utente di Dynamo registrando voci di menu personalizzate. Le estensioni standard funzionano in modo molto simile, meno l'interfaccia utente. Ad esempio, è possibile creare un'estensione che registra informazioni specifiche nella console di Dynamo. Questo scenario non richiede alcuna interfaccia utente personalizzata e pertanto potrebbe essere eseguito anche utilizzando un'estensione.

Case study dell'estensione

Seguendo l'esempio SampleViewExtension dal repository DynamoSamples su GitHub, illustreremo la procedura necessaria per creare una finestra non modale semplice che visualizzi i nodi attivi nel grafico in tempo reale. Per un'estensione della vista è necessario creare un'interfaccia utente per la finestra e associare i valori ad un modello di vista.

  1. La finestra dell'estensione della vista è stata sviluppata seguendo l'esempio SampleViewExtension nel repository su GitHub.

Anche se costruiremo l'esempio da zero, è possibile anche scaricare e creare il repository DynamoSamples come riferimento.

Il repository DynamoSamples: https://github.com/DynamoDS/DynamoSamples

Questa simulazione farà riferimento in modo specifico al progetto denominato SampleViewExtension disponibile in DynamoSamples/src/.

Come implementare un'estensione della vista

Un'estensione della vista è costituita da tre parti essenziali:

  • Un assieme contenente una classe che implementa IViewExtension e una classe che crea un modello di vista

  • Un file .xml che indica a Dynamo dove deve cercare questo assieme in fase di esecuzione e il tipo di estensione

  • Un file .xaml che associa i dati alla visualizzazione grafica e determina l'aspetto della finestra

1. Creazione della struttura del progetto

Iniziare creando un nuovo progetto Class Library denominato SampleViewExtension.

  1. Creare un nuovo progetto selezionando File > New > Project.

  2. Selezionare Class Library.

  3. Assegnare al progetto il nome SampleViewExtension.

  4. Selezionare Ok.

In questo progetto, avremo bisogno di due classi. Una classe implementerà IViewExtension e un'altra che implementerà NotificationObject. IViewExtension conterrà tutte le informazioni su come l'estensione verrà distribuita, caricata, utilizzata come riferimento ed eliminata. NotificationObject fornirà notifiche per le modifiche in Dynamo e IDisposable. Quando si verifica una modifica, il conteggio verrà aggiornato di conseguenza.

  1. Un file di classe denominato SampleViewExtension.cs che implementerà IViewExtension

  2. Un file di classe denominato SampleWindowViewMode.cs che implementerà NotificationObject

Per utilizzare IViewExtension, è necessario il pacchetto NuGet WpfUILibrary. L'installazione di questo pacchetto comporta l'installazione automatica dei pacchetti Core, Services e ZeroTouchLibrary.

  1. Selezionare WpfUILibrary.

  2. Selezionare Install per installare tutti i pacchetti dipendenti.

2. Implementazione della classe IViewExtension

Dalla classe IViewExtension determineremo cosa succede quando Dynamo viene avviato, quando l'estensione viene caricata e quando Dynamo viene chiuso. Nel file della classe SampleViewExtension.cs, aggiungere il seguente codice:

using System;
using System.Windows;
using System.Windows.Controls;
using Dynamo.Wpf.Extensions;

namespace SampleViewExtension
{

    public class SampleViewExtension : IViewExtension
    {
        private MenuItem sampleMenuItem;

        public void Dispose()
        {
        }

        public void Startup(ViewStartupParams p)
        {
        }

        public void Loaded(ViewLoadedParams p)
        {
            // Save a reference to your loaded parameters.
            // You'll need these later when you want to use
            // the supplied workspaces

            sampleMenuItem = new MenuItem {Header = "Show View Extension Sample Window"};
            sampleMenuItem.Click += (sender, args) =>
            {
                var viewModel = new SampleWindowViewModel(p);
                var window = new SampleWindow
                {
                    // Set the data context for the main grid in the window.
                    MainGrid = { DataContext = viewModel },

                    // Set the owner of the window to the Dynamo window.
                    Owner = p.DynamoWindow
                };

                window.Left = window.Owner.Left + 400;
                window.Top = window.Owner.Top + 200;

                // Show a modeless window.
                window.Show();
            };
            p.AddMenuItem(MenuBarType.View, sampleMenuItem);
        }

        public void Shutdown()
        {
        }

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

        public string Name
        {
            get
            {
                return "Sample View Extension";
            }
        } 

    }
}

La classe SampleViewExtension crea una voce di menu selezionabile per aprire la finestra e collegarla al modello di vista e alla finestra.

  • La classe public class SampleViewExtension : IViewExtension SampleViewExtension ereditata dall'interfaccia IViewExtension fornisce tutto ciò che è necessario per creare la voce di menu.

  • sampleMenuItem = new MenuItem { Header = "Show View Extension Sample Window" }; crea un elemento MenuItem e lo aggiunge al menu View.

  1. La voce di menu

  • sampleMenuItem.Click += (sender, args) attiva un evento che aprirà una nuova finestra quando si fa clic sulla voce di menu.

  • MainGrid = { DataContext = viewModel } imposta il contesto dei dati per la griglia principale nella finestra, facendo riferimento a Main Grid nel file .xaml che creeremo.

  • Owner = p.DynamoWindow imposta il proprietario della finestra a comparsa su Dynamo. Ciò significa che la nuova finestra dipende da Dynamo, pertanto azioni quali la riduzione a icona, l'ingrandimento e il ripristino di Dynamo faranno sì che la nuova finestra segua lo stesso funzionamento.

  • window.Show(); visualizza la finestra in cui sono state impostate proprietà aggiuntive.

3. Implementazione del modello di vista

Ora che sono stati definiti alcuni parametri di base della finestra, verrà aggiunta la logica per rispondere a vari eventi correlati a Dynamo e verrà richiesto all'interfaccia utente di eseguire l'aggiornamento in base a tali eventi. Copiare il seguente codice nel file della classe SampleWindowViewModel.cs:

using System;
using Dynamo.Core;
using Dynamo.Extensions;
using Dynamo.Graph.Nodes;

namespace SampleViewExtension
{
    public class SampleWindowViewModel : NotificationObject, IDisposable
    {
        private string activeNodeTypes;
        private ReadyParams readyParams;

        // Displays active nodes in the workspace
        public string ActiveNodeTypes
        {
            get
            {
                activeNodeTypes = getNodeTypes();
                return activeNodeTypes;
            }
        }

        // Helper function that builds string of active nodes
        public string getNodeTypes()
        {
            string output = "Active nodes:\n";

            foreach (NodeModel node in readyParams.CurrentWorkspaceModel.Nodes)
            {
                string nickName = node.Name;
                output += nickName + "\n";
            }

            return output;
        }

        public SampleWindowViewModel(ReadyParams p)
        {
            readyParams = p;
            p.CurrentWorkspaceModel.NodeAdded += CurrentWorkspaceModel_NodesChanged;
            p.CurrentWorkspaceModel.NodeRemoved += CurrentWorkspaceModel_NodesChanged;
        }

        private void CurrentWorkspaceModel_NodesChanged(NodeModel obj)
        {
            RaisePropertyChanged("ActiveNodeTypes");
        }

        public void Dispose()
        {
            readyParams.CurrentWorkspaceModel.NodeAdded -= CurrentWorkspaceModel_NodesChanged;
            readyParams.CurrentWorkspaceModel.NodeRemoved -= CurrentWorkspaceModel_NodesChanged;
        }
    }
}

Questa implementazione della classe del modello di vista è in ascolto di CurrentWorkspaceModel e attiva un evento quando un nodo viene aggiunto o rimosso dall'area di lavoro. Ciò genera una modifica della proprietà che notifica all'interfaccia utente o agli elementi associati che i dati sono stati modificati e devono essere aggiornati. Viene chiamato il getter ActiveNodeTypes che chiama internamente una funzione helper aggiuntiva getNodeTypes(). Questa funzione esegue l'iterazione di tutti i nodi attivi nell'area di disegno, compila una stringa contenente i nomi di tali nodi e restituisce questa stringa al nostro binding nel file .xaml da visualizzare nella finestra a comparsa.

Con la logica di base dell'estensione definita, ora specificheremo i dettagli dell'aspetto della finestra con un file .xaml. Tutto ciò che server è una semplice finestra che visualizzi la stringa tramite l'associazione della proprietà ActiveNodeTypes in TextBlock Text.

  1. Fare clic con il pulsante destro del mouse sul progetto e selezionare Add > New Item....

  2. Selezionare il modello di controllo utente che verrà modificato per creare una finestra.

  3. Assegnare un nome al nuovo file SampleWindow.xaml.

  4. Selezionare Add.

Nel codice della finestra .xaml, dovremo associare SelectedNodesText ad un blocco di testo. Aggiungere il seguente codice a SampleWindow.xaml:

<Window x:Class="SampleViewExtension.SampleWindow"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:SampleViewExtension"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
            Width="500" Height="100">
    <Grid Name="MainGrid" 
          HorizontalAlignment="Stretch"
          VerticalAlignment="Stretch">
        <TextBlock HorizontalAlignment="Stretch" Text="{Binding ActiveNodeTypes}" FontFamily="Arial" Padding="10" FontWeight="Medium" FontSize="18" Background="#2d2d2d" Foreground="White"/>
    </Grid>
</Window>
  • Text="{Binding ActiveNodeTypes}" associa il valore della proprietà ActiveNodeTypes in SampleWindowViewModel.cs al valore TextBlock Text nella finestra.

Ora inizializzeremo la finestra di esempio nel file di backing .xaml C# SampleWindow.xaml.cs. Aggiungere il seguente codice a SampleWindow.xaml:

using System.Windows;

namespace SampleViewExtension
{
    /// <summary>
    /// Interaction logic for SampleWindow.xaml
    /// </summary>
    public partial class SampleWindow : Window
    {
        public SampleWindow()
        {
            InitializeComponent();
        }
    }
}

L'estensione della vista è ora pronta per essere creata e aggiunta a Dynamo. Dynamo richiede un file xml per registrare il nostro output .dll come estensione.

  1. Fare clic con il pulsante destro del mouse sul progetto e selezionare Add > New Item....

  2. Selezionare il file XML.

  3. Assegnare un nome al file SampleViewExtension_ViewExtensionDefinition.xml.

  4. Selezionare Add.

  • Il nome del file segue lo standard di Dynamo per fare riferimento ad un assieme di estensione, come indicato di seguito: "extensionName"_ViewExtensionDefinition.xml

Nel file xml, aggiungere il seguente codice per indicare a Dynamo dove cercare l'assieme di estensione:

<ViewExtensionDefinition>
  <AssemblyPath>C:\Users\username\Documents\Visual Studio 2015\Projects\SampleViewExtension\SampleViewExtension\bin\Debug\SampleViewExtension.dll</AssemblyPath>
  <TypeName>SampleViewExtension.SampleViewExtension</TypeName>
</ViewExtensionDefinition>
  • In questo esempio, è stato creato l'assieme nella cartella di progetti di default di Visual Studio. Sostituire la destinazione <AssemblyPath>...</AssemblyPath> con la posizione dell'assieme.

L'ultimo passaggio consiste nel copiare il file SampleViewExtension_ViewExtensionDefinition.xml nella cartella viewExtensions di Dynamo, che si trova nella directory di installazione di Dynamo Core C:\Program Files\Dynamo\Dynamo Core\1.3\viewExtensions. È importante notare che sono presenti cartelle separate per extensions e viewExtensions. Il posizionamento del file xml nella cartella errata potrebbe causare errori di caricamento in fase di esecuzione.

  1. Il file .xml copiato nella cartella viewExtensions di Dynamo

Questa è un'introduzione di base alle estensioni delle viste. Per un case study più sofisticato, vedere il pacchetto DynaShape, un progetto open source su GitHub. Il pacchetto utilizza un'estensione della vista che consente la modifica in tempo reale nella vista modello di Dynamo.

È possibile scaricare un programma di installazione del pacchetto per DynaShape dal forum di Dynamo: https://forum.dynamobim.com/t/dynashape-published/11666

Il codice sorgente può essere clonato da GitHub: https://github.com/LongNguyenP/DynaShape

Last updated