Overview
With the Plugin approach, care must be taken with both the Project location and the Project build output settings. As mentioned on the main page, correct Project location allows Project References to be properly resolved. Build settings enable debugging.
Plugin based Project Template (VS 2019) can be downloaded here.
What is Created
The screenshot below is of a Map based project, but the Plugin Project will also include these advantages.
Notice also the “Sample.dwg” which includes Tsls demonstrating how to work with both Map and Plugin based .dlls
What the Sample is doing
Plugin Properties offer advantages for standard Tsl Properties, but there are required steps to enable them. Project Debug settings are required to enable debugging. Here is a basic list, feel free to contact me directly for further information.
Properties in the ViewModel
PropDouble entries should be of type DoublePropertyVm
PropInt entries should be of type IntegerPropertyVm
PropString entries should be of type StringPropertyVm
Any Tsl Property which needs to be exposed as a list needs to be of type EnumerablePropertyVm
The ViewModel Constructor (TslCustomUIViewModel in the example)
Takes a TslInstance, and needs to store this locally in a private field
Initializes each ViewModel property, usually by calling a dedicated method (described below)
InitializeViewModesl()
This method instantiates each of the ViewModels listed above
In the sample, I do this by referencing the property index. You could also check the Name
You might need other custom actions here. The Template provides a sample which constructs one of the List type Properties in C#, instead of using a list defined on the Tsl side
RecordPropertyViewModels()
This method takes all of your ViewModels (which need to have already been instantiated) and adds them to a local list ( of type List<TslPropertyVm> )
The List is used when a Catalog entry is selected
HookIntoPropertyChanged()
This method also requires that all ViewModels are instantiated and added to the _allProperties list
In the sample I’m using the newer WeakEventManager approach to registering handlers for events. This is fairly identical (but somewhat safer) to the traditional C# syntax Event += EventHandler. The traditional syntax can result in memory leaks if you fail to call -= to remove the handler, WeakEventManager deals with this automatically
We are subscribing to the PropertyChanged event in each TslPropertyVm so that _tslInstance can be updated when the user edits one of the ViewModel Properties. This method is described next
UpdateValuesInTslInstance(object sender, PropertyChangedEventArgs e)
Whenever one of the Properties of TslCustomUIViewModel are edited, this method is called since we subscribed to the PropertyChanged event
The check against the local bool, PropertiesBeingUpdated is done in order to bypass this method when a Catalog entry has been activated
In the sample, I simply loop against the recorded Properties and set all of them. Alternatively, you could check the sender, or the Property name (which is recorded in the PropertyChangedEventArgs) and set just that value. Either approach is valid.
You might take other actions here, for instance in the sample I filter one list to show only numbers bigger than the one entered into DoubleProp, but only when that entry has changed.
TslCustomUISample
Inherits from IPluginUI
Is adorned with the PluginUI attribute, which needs to be declared with the Tsl script name you wish the dialog to be active for
The Show method is what hsb will call when it finds the plugin, the UserControl you return is plugged into the Properties dialog instead of the default control.
What You Need To Do
The sample shows how to handle each Property type available in Tsl. You can either replace each of these with your own (in which case you’ll need to update the attribute in TslCustomUI.PluginUI.cs), or create an entirely new View and ViewModel in parallel and leave the sample code intact. You would simply create a new class of type IPluginUI, adorn it with the PluginUI(<yourScriptName>) attribute, and rewrite the Show(object plugin) method to cite your new classes.
In order to enable debugging, Rt-click the Project and go into its Properties. On the Debug tab, browse to your local installation of ACA:
Although not shown in my screenshot, you can also provide a file path in the “Command Line Arguments” box below to get ACA to automatically load a particular .dwg
Also make sure the Build => Output path for the Debug configuration is set to the proper folder in the hsbcad installation you will run for debugging. The relative path shown here will work if your C# Project is in the recommended file location, else you’ll need to provide an appropriate one (which does not necessarily need to be relative):