Rozszerzenia
Rozszerzenia są zaawansowanym narzędziem programistycznym w ekosystemie dodatku Dynamo. Umożliwiają programistom sterowanie funkcjami niestandardowymi opartymi na interakcjach i logice dodatku Dynamo. Rozszerzenia można podzielić na dwie główne kategorie, rozszerzenia i rozszerzenia widoku. Jak sugeruje nazwa, struktura rozszerzeń widoku umożliwia rozszerzenie interfejsu użytkownika dodatku Dynamo przez zarejestrowanie niestandardowych elementów menu. Zwykłe rozszerzenia działają w bardzo podobny sposób, ale bez interfejsu użytkownika. Przykładowo można utworzyć rozszerzenie rejestrujące określone informacje w konsoli dodatku Dynamo. Ten scenariusz nie wymaga niestandardowego interfejsu użytkownika i dlatego można go zrealizować również za pomocą rozszerzenia.
Analiza przypadku rozszerzenia
Korzystając z przykładu SampleViewExtension z repozytorium DynamoSamples z serwisu Github, przeanalizujemy czynności niezbędne do utworzenia prostego okna niemodalnego, w którym wyświetlane są aktywne węzły na wykresie w czasie rzeczywistym. Rozszerzenie widoku wymaga utworzenia interfejsu użytkownika dla tego okna i powiązania wartości z modelem widoku.

To okno rozszerzenia widoku opracowano na podstawie przykładu SampleViewExtension z repozytorium Github.
Mimo że utworzymy tu ten przykład od podstaw, można również pobrać i skompilować repozytorium DynamoSamples, a następnie używać go jako odniesienia.
Repozytorium DynamoSamples: https://github.com/DynamoDS/DynamoSamples
W tym przewodniku będziemy odwoływać się konkretnie do projektu o nazwie SampleViewExtension znajdującego się w folderze
DynamoSamples/src/
.
Jak zaimplementować rozszerzenie widoku
Rozszerzenie widoku zawiera trzy zasadnicze części:
Zespół zawierający klasę z zaimplementowanym interfejsem
IViewExtension
oraz klasę tworzącą model widokuPlik
.xml
informujący dodatek Dynamo, gdzie należy szukać tego zespołu w czasie wykonywania oraz jaki jest typ rozszerzeniaPlik
.xaml
, który wiąże dane z wyświetlaniem grafiki i określa wygląd okna
1. Tworzenie struktury projektu
Rozpocznij od utworzenia nowego projektu Class Library
o nazwie SampleViewExtension
.


Utwórz nowy projekt, wybierając opcję
File > New > Project
Wybierz opcję
Class Library
Nadaj projektowi nazwę
SampleViewExtension
Wybierz przycisk
Ok
W tym projekcie będą potrzebne dwie klasy. W jednej klasie zostanie zaimplementowany interfejs IViewExtension
, a w drugiej — klasa NotificationObject.
Interfejs IViewExtension
będzie zawierać wszystkie informacje o sposobie wdrażania, wczytywania, i usuwania rozszerzenia oraz odwoływania się do niego. Klasa NotificationObject
będzie udostępniać powiadomienia o zmianach w dodatku Dynamo i interfejsie IDisposable
. Po wprowadzeniu zmiany liczba zostanie odpowiednio zaktualizowana.

Plik klasy o nazwie
SampleViewExtension.cs
, w której zostanie zaimplementowany interfejsIViewExtension
Plik klasy o nazwie
SampleWindowViewMode.cs
, w której zostanie zaimplementowana klasaNotificationObject
Aby można było użyć interfejsu IViewExtension
, potrzebny jest pakiet NuGet WpfUILibrary. Zainstalowanie tego pakietu spowoduje automatyczne zainstalowanie pakietów Core, Services i ZeroTouchLibrary.

Wybierz pakiet WpfUILibrary
Wybierz opcję
Install
, aby zainstalować wszystkie pakiety zależne
2. Implementowanie klasy IViewExtension
W klasie IViewExtension
określimy, co się dzieje podczas uruchamiania dodatku Dynamo, gdy rozszerzenie jest wczytywane i gdy dodatek Dynamo zostaje zamknięty. W pliku klasy SampleViewExtension.cs
dodaj następujący kod:
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";
}
}
}
}
Klasa SampleViewExtension
tworzy element menu, który można kliknąć, służący do otwierania okna, i łączy go z oknem i modelem widoku.
Instrukcja
public class SampleViewExtension : IViewExtension
SampleViewExtension
powoduje dziedziczenie po interfejsieIViewExtension
i udostępnia wszystkie funkcje potrzebne do utworzenia elementu menu.Instrukcja
sampleMenuItem = new MenuItem { Header = "Show View Extension Sample Window" };
tworzy element MenuItem i dodaje go do menuView
.

Element menu
Instrukcja
sampleMenuItem.Click += (sender, args)
wyzwala zdarzenie, które powoduje otwarcie nowego okna po kliknięciu elementu menuInstrukcja
MainGrid = { DataContext = viewModel }
ustawia kontekst danych dla siatki głównej w oknie, odwołując się do elementuMain Grid
w pliku.xaml
, który zostanie utworzonyInstrukcja
Owner = p.DynamoWindow
ustawia dodatek Dynamo jako właściciela wyskakującego okna. Oznacza to, że nowe okno jest zależne od dodatku Dynamo, więc takie operacje jak zminimalizowanie, zmaksymalizowanie i przywrócenie dodatku Dynamo spowodują, że nowe okno będzie działało tak samoMetoda
window.Show();
wyświetla okno, w którym ustawiono dodatkowe właściwości okna
3. Implementowanie modelu widoku
Po ustaleniu niektórych podstawowych parametrów okna dodamy logikę reagowania na różne zdarzenia związane z dodatkiem Dynamo i poinstruujemy interfejs użytkownika, aby dokonał aktualizacji na podstawie tych zdarzeń. Skopiuj następujący kod do pliku klasy 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;
}
}
}
Ta implementacja klasy modelu widoku nasłuchuje elementu CurrentWorkspaceModel
i wyzwala zdarzenie w przypadku dodania lub usunięcia węzła z obszaru roboczego. Powoduje to zgłoszenie zmiany właściwości i powiadomienie interfejsu użytkownika lub powiązanych elementów o zmianie danych i konieczności ich zaktualizowania. Wywoływany jest mechanizm pobierania ActiveNodeTypes
, który wewnętrznie wywołuje dodatkową funkcję pomocniczą getNodeTypes()
. Ta funkcja iteruje przez wszystkie aktywne węzły w obszarze rysunku, wypełnia ciąg zawierający nazwy tych węzłów i zwraca ten ciąg do powiązania w pliku .xaml do wyświetlenia w wyskakującym oknie.
Po zdefiniowaniu logiki podstawowej rozszerzenia określimy teraz szczegóły wyglądu okna za pomocą pliku .xaml
. Wystarczy proste okno, w którym ten ciąg będzie wyświetlany za pomocą powiązania właściwości ActiveNodeTypes
w kontrolce TextBlock
Text
.

Kliknij prawym przyciskiem myszy projekt i wybierz pozycję
Add > New Item...
Wybierz szablon kontroli użytkownika, który zmienimy w celu utworzenia okna
Nadaj nowemu plikowi nazwę
SampleWindow.xaml
Wybierz opcję
Add
W kodzie .xaml
okna należy powiązać element SelectedNodesText
z blokiem tekstowym. Dodaj następujący kod do pliku 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>
Instrukcja
Text="{Binding ActiveNodeTypes}"
wiąże wartość właściwościActiveNodeTypes
w plikuSampleWindowViewModel.cs
z wartościąText
elementuTextBlock
w oknie.
Teraz zainicjujemy okno przykładowe w pliku zaplecza pliku C# .xaml: SampleWindow.xaml.cs
. Dodaj następujący kod do pliku SampleWindow.xaml
:
using System.Windows;
namespace SampleViewExtension
{
/// <summary>
/// Interaction logic for SampleWindow.xaml
/// </summary>
public partial class SampleWindow : Window
{
public SampleWindow()
{
InitializeComponent();
}
}
}
Rozszerzenie widoku jest teraz gotowe do skompilowania i dodania do dodatku Dynamo. Dodatek Dynamo wymaga pliku xml
, aby zarejestrować wynikowy plik .dll
jako rozszerzenie.

Kliknij prawym przyciskiem myszy projekt i wybierz pozycję
Add > New Item...
Wybierz plik XML
Nadaj plikowi nazwę
SampleViewExtension_ViewExtensionDefinition.xml
Wybierz opcję
Add
Ta nazwa pliku jest zgodna ze standardem dodatku Dynamo dotyczącego odwoływania się do zespołu rozszerzenia:
"extensionName"_ViewExtensionDefinition.xml
W pliku xml
dodaj następujący kod, aby wskazać dodatkowi Dynamo, gdzie ma szukać zespołu rozszerzenia:
<ViewExtensionDefinition>
<AssemblyPath>C:\Users\username\Documents\Visual Studio 2015\Projects\SampleViewExtension\SampleViewExtension\bin\Debug\SampleViewExtension.dll</AssemblyPath>
<TypeName>SampleViewExtension.SampleViewExtension</TypeName>
</ViewExtensionDefinition>
W tym przykładzie skompilowaliśmy zespół w domyślnym folderze projektu programu Visual Studio. Zastąp położenie docelowe
<AssemblyPath>...</AssemblyPath>
położeniem zespołu.
Ostatnią czynnością jest skopiowanie pliku SampleViewExtension_ViewExtensionDefinition.xml
do folderu rozszerzeń widoku dodatku Dynamo znajdującego się w katalogu instalacyjnym Dynamo Core C:\Program Files\Dynamo\Dynamo Core\1.3\viewExtensions
. Należy pamiętać, że istnieją oddzielne foldery dla rozszerzeń extensions
i viewExtensions
. Umieszczenie pliku xml
w niewłaściwym folderze może spowodować błąd podczas wczytywania pliku w trakcie wykonywania.

Plik
.xml
skopiowany do folderu rozszerzeń widoku dodatku Dynamo
Jest to podstawowe wprowadzenie do rozszerzeń widoku. Bardziej zaawansowaną analizę przypadku zawiera pakiet DynaShape, projekt open source w serwisie GitHub. Ten pakiet zawiera rozszerzenie widoku umożliwiające edycję na żywo w widoku modelu dodatku Dynamo.
Instalator pakietu DynaShape można pobrać z forum dodatku Dynamo: https://forum.dynamobim.com/t/dynashape-published/11666
Kod źródłowy można sklonować z serwisu GitHub: https://github.com/LongNguyenP/DynaShape
Last updated