Kanzi Studio plugins extend the functionality of Kanzi Studio and run in Kanzi Studio. Use a Kanzi Studio plugin to:
You can present a Kanzi Studio plugin either:
The default UI framework for creating Kanzi Studio window plugins is WPF. However, you can use frameworks that run on HTML using the web browser control in WPF, or other frameworks by embedding the content using WPF HwndHost control that hosts a win32 window as an element in WPF content.
The Kanzi Studio plugin interface is provided as a .NET framework assembly. You can find it in <KanziInstallation>/Studio/Bin/PluginInterface.dll. The plugin interface provides access to data and commands in Kanzi Studio. When you want to use a Kanzi Studio plugin with different versions of Kanzi Studio, build the plugin with the PluginInterface.dll from each version of Kanzi Studio where you want to use that plugin.
To develop a Kanzi Studio window plugin:
To find detailed information about the Kanzi Studio plugin interface see:
Kanzi Studio window plugins are plugins that you use in a Kanzi Studio window and have a user interface. For example, use the window plugins to create an editor or to visualize the content in your project.
Here you create the base for a Kanzi Studio window plugin where you then add functionality that extends the functionality of Kanzi Studio.
To create a Kanzi Studio window plugin:
System.ComponentModel.Composition
System.XAML
In the Solution Explorer right-click the project name, select Properties, and:
UserControl1.xaml.cs
file and add the using directive for the Kanzi Studio plugin interface:using Rightware.Kanzi.Studio.PluginInterface;
UserControl1
class to implement the PluginWindow
interface:public partial class UserControl1 : UserControlto
public partial class UserControl1 : UserControl, PluginWindow
PluginWindow
interface.PluginWindow
, click , and select Implement Interface.KanziStudio
interface to the UserControl1
class. KanziStudio
interface is the entry point for operating with the Kanzi Studio plugin API.private KanziStudio studio;
throw new NotImplementedException();
Make sure that your plugin handles all its internal exceptions and does not let them reach the Kanzi Studio interface.
For example, set the functions in theUserControl1
class:UserControl1
the studio
parameter. This enables you to instantiate the UserControl1
and supply studio
as an argument in the Class1.cs
file.public UserControl1(KanziStudio studio) { this.studio = studio; InitializeComponent(); }
Icon
function to set the plugin window icon shown in the top-left corner of the plugin window:public string Icon { get { return ""; } }
SerializeState
function to save the state of the plugin window. Kanzi Studio calls this function when you close the plugin window. When you open the plugin window again, Kanzi Studio passes the same state as a parameter as it creates the plugin window.null
, Kanzi Studio does not remember the state of the window.public PluginWindowState SerializeState() { return null; }
Title
function to set the text you want to show as the title of the plugin window. For example, set it to:public string Title { get { return "Plugin title"; } }
Dispose
function to clean up when closing the plugin window. For example, here you can release all resources you use in the plugin, and if your plugin subscribes to any events, unsubscribe these events here. Kanzi Studio calls this function when user closes a plugin window.Class1.cs
file and add the using directive for the System.ComponentModel.Composition
and the Kanzi Studio plugin interface:using System.ComponentModel.Composition; using Rightware.Kanzi.Studio.PluginInterface;
Class1
class to implement the PluginWindowFactory
interface, which you implement in the Class1
class. Kanzi uses this class to create the plugin. Kanzi Studio first gets the factory and defines the name of the plugin, the size of the window, if the plugin has a window, and from where in Kanzi Studio users can launch the plugin.public class Class1to
public class Class1 : PluginWindowFactory
PluginWindowFactory
interface.PluginWindowFactory
, click , and select Implement Interface.PluginWindowFactory
interface to be the plugin content for Kanzi Studio. This way Kanzi Studio knows that the .dll is a plugin.[Export(typeof(PluginContent))]
throw new NotImplementedException();
Make sure that your plugin handles all its internal exceptions and does not let them reach the Kanzi Studio interface.
For example, set the functions in theClass1
class to:CreateWindow
function to instantiate the UserControl1
and supply studio
as an argument. You added the studio
parameter to the UserControl1
in the UserControl1.xaml.cs
file.public PluginWindow CreateWindow(PluginWindowState state) { return new UserControl1(studio); }
DefaultHeight
and DefaultWidth
functions to the height and width of the window of your plugin. For example, to make a 400 by 400 pixel plugin window use:get { return 400; }
CanExecute
function to set whether users can launch your plugin, and where they can launch your plugin:
false
, Kanzi Studio shows the plugin in the main menu and the context menu, but users cannot launch the plugin.true
, users can launch the plugin.Kanzi Studio provides the KanziStudio
object to plugins. The KanziStudio
object is the root object for data access and provides the current project, available commands, global undo and redo, and events related to project opening and closing.
For example, use this to enable the command only when a Kanzi Studio project is open
private KanziStudio studio; public bool CanExecute(PluginCommandParameter parameter) { return this.studio != null && this.studio.ActiveProject != null; }
CommandPlacement
function to set the menu name of the plugin, and where you want to show the command to launch the plugin:
ContextMenuPlacement.NONE
.ContextMenuPlacement.PROJECT_ITEM
.public CommandPlacement CommandPlacement { get { return new CommandPlacement("myPluginMenu", ContextMenuPlacement.NONE, false, null); } }
Description
function to set a brief description of what your Kanzi Studio plugin does. Kanzi Studio shows this description as a tooltip when a user hovers the mouse pointer over the plugin name in the menu.public string Description { get { return "A tooltip with short description of what the plugin does."; } }
DisplayName
function to show the plugin name in the Kanzi Studio menu where you can launch the plugin.public string DisplayName { get { return "Plugin display name"; } }
Name
function to set the internal name of your plugin. Kanzi uses the internal name of the plugin so that you can change the display name of your plugin without additional changes to the plugin.public string Name { get { return "Internal plugin name"; } }
Initialize
function to place studio
to a member variable.public void Initialize(KanziStudio studio) { this.studio = studio; }
Here you created just the base structure for your Kanzi Studio window plugin, which only opens an empty window. To make your plugin do more than that, add functionality to the window. See Adding functionality to your Kanzi Studio window plugin and Grouping project changes in your Kanzi Studio window plugin.
To further develop your Kanzi Studio plugin, see Overview of Kanzi Studio plugin interface and Kanzi Studio plugin interface API reference.
To build and run a Kanzi Studio plugin:
Copy the Kanzi Studio plugin .dll to the %ProgramData%\Rightware\<KanziVersion>\plugins directory.
If the plugins directory does not exist in %ProgramData%\Rightware\<KanziVersion>, create it.
After you create the base for a Kanzi Studio window plugin, add functionality to your plugin so that it does something useful. Here you create a plugin that shows the kzb file URL of the currently selected node or resource.
To add functionality to your Kanzi Studio window plugin:
PluginWindow
interface.UserControl1.xaml.cs
class file.PluginWindow
interface add the code that your plugin executes when you interact with the plugin in the plugin window.public partial class UserControl1 : UserControl, PluginWindow { private KanziStudio studio; public UserControl1(KanziStudio studio) { this.studio = studio; InitializeComponent(); // Subscribe to the SelectionChanged event to find out when the selection of a node or a resource changes. studio.SelectionChanged += Studio_SelectionChanged; // Set the contents of the plugin window. Populate(); } // When the currently selected project item changes, set the contents of the plugin window. private void Studio_SelectionChanged(object sender, EventArgs e) { Populate(); } // Set the text in the controls that show the name and kzb file URL of the currently selected project item. public void Populate() { var currentSelection = studio.SelectedItems.FirstOrDefault(); this.selectionTextBlock.Text = (currentSelection != null) ? currentSelection.Name : "< no project item selected >"; this.kzbUrlTextBox.Text = (currentSelection != null) ? currentSelection.KzbUrl : " "; } ... // Set the title of the plugin window. public string Title { get { return "Project item kzb file URL"; } } ... // Dispose of the resources used by the window. public void Dispose() { if (studio != null) { this.studio.SelectionChanged -= Studio_SelectionChanged; } } ... }
UserControl1.xaml
file and replace<Grid> </Grid>with
<StackPanel Margin="5"> <Label Content="Project Item" /> <TextBlock x:Name="selectionTextBlock" Margin="10,5" /> <Label Content="kzb file URL" /> <TextBox x:Name="kzbUrlTextBox" Margin="10,5" IsReadOnly="True" /> </StackPanel>
Group project changes in your Kanzi Studio window plugin to make the changes appear as one command to the Kanzi Studio user. This way you set undo and redo commands to affect the whole group of changes instead of individual changes.
For example, group project changes when your Kanzi Studio window plugin applies a series of modifications to the project when the user clicks a button, and you want Kanzi Studio to undo all those modifications at once when the user selects > Undo.
Use batch modification to group a series of changes your Kanzi Studio window plugin applies to the project. When you use batch modification, the object which listens to the modified events can skip the events which happen during the batch modification and apply all the changes when the batch modification finishes.
To group project changes in your Kanzi Studio window plugin:
PluginWindow
interface.UserControl1.xaml.cs
class file.PluginWindow
interface add the code that your plugin executes when you interact with the plugin in the plugin window.// This function returns true if a guide with a given name already exists. private bool GuideExists(string guideName) { bool exists = false; var guides = studio.ActiveProject.Guides; foreach (var guide in guides) { var name = guide.Get(Properties.Name); if (name == guideName) { exists = true; } } return exists; } // This function creates the guides. private void CreateGuides(int step, int count, bool isVertical) { var guides = studio.ActiveProject.Guides; for (int i = 1; i <= count; i++) { String guideName; Vector guidePosition; var coordinate = i * step; // Set guide position and name. if (isVertical) { guidePosition = new Vector(coordinate, 0); guideName = "Guide_V" + Convert.ToString(coordinate); } else { guidePosition = new Vector(0, coordinate); guideName = "Guide_H" + Convert.ToString(coordinate); } // Check if a guide with the same name already exists bool exists = GuideExists(guideName); if (!exists) { // Create a new guide. var guide = studio.ActiveProject.CreateProjectItem<Guide>(guideName, null); // Set the position of the guide. guide.Set(Properties.GuidePosition, guidePosition); // For vertical guides, set the Rotation property. if (isVertical) { guide.Set(Properties.GuideRotation, (float)Math.PI/2); } } } }
BeginBatchModification
and CommitBatchModification
functions.private void Button_Click(object sender, RoutedEventArgs e) { // Distance between horizontal guides var horizontalStep = Convert.ToUInt16(hStepInput.Text); // Number of horizontal guides int horizontalCount = Convert.ToUInt16(hCountInput.Text); // Distance between vertical guides var verticalStep = Convert.ToUInt16(vStepInput.Text); // Number of vertical guides int verticalCount = Convert.ToUInt16(vCountInput.Text); // Begin a batch modification named Create Guides studio.ActiveProject.BeginBatchModification("Create Guides"); // Call the functions for the code you want to execute inside the batch. CreateGuides(horizontalStep, horizontalCount, false); CreateGuides(verticalStep, verticalCount, true); // Finish the batch modification studio.ActiveProject.CommitBatchModification(); }
UserControl1.xaml
file and replace<Grid> </Grid>with
<StackPanel HorizontalAlignment="Center"> <Grid Margin="0,10"> <Grid.ColumnDefinitions> <ColumnDefinition Width="150" /> <ColumnDefinition Width="45" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <Label Margin="0,0,0,2" Grid.Column="0" Grid.Row="0" FontWeight="Bold">Horizontal Guides</Label> <Label Margin="5,2,0,2" Grid.Column="0" Grid.Row="1">Number of guides</Label> <TextBox Margin="0,2" Grid.Column="1" Grid.Row="1" Name="hCountInput" Text="10" /> <Label Margin="5,2,0,2" Grid.Column="0" Grid.Row="2">Distance between guides</Label> <TextBox Margin="0,2" Grid.Column="1" Grid.Row="2" Name="hStepInput" Text="100" /> <Label Margin="0,10,0,2" Grid.Column="0" Grid.Row="3" FontWeight="Bold">Vertical Guides</Label> <Label Margin="5,2,0,2" Grid.Column="0" Grid.Row="4">Number of guides</Label> <TextBox Margin="0,2" Grid.Column="1" Grid.Row="4" Name="vCountInput" Text="10" /> <Label Margin="5,2,2,2" Grid.Column="0" Grid.Row="5">Distance between guides</Label> <TextBox Margin="0,2" Grid.Column="1" Grid.Row="5" Name="vStepInput" Text="100" /> </Grid> <Button Padding="5,3" Content="Create Guides" Click="Button_Click" /> </StackPanel>
To see the guides in you Kanzi Studio project, in the Preview click to enter the Analyze mode, right-click , and select Rulers and guides.
Overview of Kanzi Studio plugin interface
Kanzi Studio plugin interface API reference
Installing Kanzi Studio plugins
Creating Kanzi Studio command plugins