v26.2 plugin updates
The goal of this document is to outline the changes that are required to update an HH DM plugin from v26.1 to v26.2.
Please note that not all changes may apply to all plugins.
Preview version
To make it easier to migrate the plugin a preview version of HH Data Management v26.2 has been made available. Due to the software needing to download a data migration from the server before being able to function this version is not runnable, it can only be used to build the plugin. This release contains only minor breaking changes and therefore we believe that this should be sufficient for plugins to be updated.
Downloading and running the client
If you do not have access to this version, please let us know and it will be added to your account. The preview version is available on the Other → Releases page of the website:

The version can also be downloaded directly using this link: https://hh-dev.com/latest/HHDM-v26.2
Please note that this version is portable, meaning that it doesn't need to be installed. Unzip the downloaded directory and run the file HHDev.DataManagement.Client.HHDataManagement.exe.
Plugin settings update
To make sure the references are linked to the right version of HH DM, you will need to put the path to the HH DM 26.2 preview version on your computer in the project file of the plugin:

Example plugin
Please see https://github.com/hh-development/HHDev.HHDM.DesktopPlugin/compare/master...release/v26.2 for an example commit of a simple plugin being updated.
Breaking changes
PluginInfo.json
The TargetVersionNumber needs to be changed to "26.2". Make sure the TargetVersionNumber is added to the PluginInfo.json, if it doesn't exist yet.
Project changes
HHDev.Core.NETFramework and HHDev.Core.NETCore projects removed
The HHDev.Core.NETFramework and HHDev.Core.NETCore projects have both been removed. Neither assembly is produced by the build anymore, so any <Reference> to them in your plugin's .csproj must be deleted, otherwise the reference will fail to resolve. All functionality has been moved to other HHDev.Core projects, mainly HHDev.Core.NETStandard.
Name changes
There have been a number of namespace and class name changes throughout the codebase. Mainly this is moving functionality from HHDev.DataManagement.* namespaces to HHDev.Core.* namespaces. The reason for this is an internal requirement to reuse these classes in other projects outside HH Data Management.
Namespace changes
The namespace (and assembly) for some classes has changed. In general, these changes move classes from the HHDev.DataManagement.Client.Wpf assembly to the HHDev.Core.WPF assembly. However, in some cases the types may have moved to HHDev.Core, HHDev.Core.NETStandard or HHDev.Core.Windows.
| Old namespace | New namespace |
|---|---|
HHDev.DataManagement.Client.Wpf.Controls | HHDev.Core.WPF.Controls |
HHDev.DataManagement.Client.Wpf.Controls.HHPopupWindow | HHDev.Core.WPF.Controls.HHPopupWindow |
HHDev.DataManagement.Client.Wpf.Controls.Ribbon | HHDev.Core.WPF.Controls.Ribbon |
HHDev.DataManagement.Client.Wpf.Graphing | HHDev.Core.WPF.Graphing |
HHDev.DataManagement.Client.Wpf.Views | HHDev.Core.WPF.Views |
HHDev.DataManagement.Client.Wpf.Helpers | HHDev.Core.WPF.Helpers |
HHDev.DataManagement.Client.Wpf.Converters | HHDev.Core.WPF.Converters |
HHDev.DataManagement.Client.Wpf.Layout | HHDev.Core.WPF.Layout |
Please note that the Controls, Helpers and Converters namespace moves above are not a wholesale move of every type in that namespace — only some types moved, and the rest remain in the original HHDev.DataManagement.Client.Wpf.* namespace. If a type can no longer be found in the new namespace, check whether it is still in the old one before assuming it was renamed or removed.
A few other namespace moves worth calling out individually:
eUiElementPermissionLevelmoved fromHHDev.DataManagement.CoretoHHDev.Core.Enums.- The
oxy:HHPlotViewcontrol moved fromHHDev.DataManagement.Client.Wpf.Graphingtographing:HHPlotViewinHHDev.Core.WPF.Graphing. ISqlGeneratormoved fromHHDev.Sync.Core.SqlGeneratorstoHHDev.Core.NETStandard.Database.SqlGenerators.BaseViewModelnow lives inHHDev.Core.NETStandard.ViewModels.ICustomizeUserInterfacePluginandViewModelMappingnow live inHHDev.Core.WPF.Plugins.- The
LoadViewFromUriextension method (used to load a view's XAML from a URI) moved toHHDev.Core.WPF.Helpers. - The ribbon-building extension methods
AddButtonandAddCheckbox(and theirRibbonButtonConfig/RibbonCheckboxConfig/RibbonComboBoxConfigconfig classes) moved toHHDev.Core.WPF.Views. Since these previously resolved implicitly through ausingyour plugin likely already had, you will need to add an explicitusing HHDev.Core.WPF.Views;to any view that builds a ribbon page. WindowsFileHelperswas renamed toFileHelperFunctionsand moved toHHDev.Core.NETStandard.Helpers.HHDev.Core.NETCorehelpers have been replaced byHHDev.Core.NETStandard(see the project removal note above). As part of this,GlobalServices.UiService.PostOnUiThread(...)has been marked obsolete in favor ofNetStandardContainer.Instance.UiService.PostOnUiThread(...).ProcessHelpersmoved fromHHDev.Core.NETCore.HelperstoHHDev.Core.NETStandard.Helpers— check for fully-qualified usages too, not justusingdirectives.BoxPlotItemModelnow lives inHHDev.Core.NETStandard.Graphing.Models.MainWindowViewwas renamed toHHMainWindowViewand lives inHHDev.Core.WPF.Views.ZonedDatePickerItem4-arg constructor: last parameter changed from event/context object tostring timeZone.
Class name changes
- BaseView renamed:
HHDev.DataManagement.Client.Wpf.Views.BaseViewhas been renamed toHHDev.DataManagement.Client.Wpf.Views.HHDMBaseView- All plugin views inheriting from
BaseViewmust be updated to inherit fromHHDMBaseView. - XAML RelativeSource and AncestorType bindings referencing
views:BaseViewshould be updated toviews:HHDMBaseView.
- Ribbon control types renamed:
HHDMRibbonPageGroup→HHRibbonPageGroupHHDMRibbonPageModel→HHRibbonPageModelHHDMBarButtonItem→HHBarButtonItemHHDMBarStaticItem→HHBarStaticItemHHDMBarEditItem→HHBarEditItem
CustomDataTemplateSelector→ColumnDataTemplateSelector(in HHDev.Core.WPF data grid namespace)BaseSetupSheetTextbox(HHDev.DataManagement.Client.Wpf.Controls) →HHTextBox(HHDev.Core.WPF.Controls)AppGlobals.UserDataFilePathwas removed; useNetStandardContainer.Instance.UserDataFilePathinstead.- A number of
WpfContainerstatic members were moved behind a newWpfContainer.WpfInstanceaccessor, for example:WpfContainer.ApplicationSettings→WpfContainer.WpfInstance.ApplicationSettingsWpfContainer.ThemeService→WpfContainer.WpfInstance.ThemeService
- The
SetWindowStartupLocation()extension methods onSystem.Windows.Windownow live inHHDev.Core.WPF.Helpers(WindowHelpers) — add ausing HHDev.Core.WPF.Helpers; HHDev.CanopyApi.dllhas been removed from HH DM. If your plugin needs it, it is still available via the NuGet packageHHDev.CanopyApi.
Flat model changes
IBasicEntityFlatModel
The following properties have been changed on the IBasicEntityFlatModel interface:
Dictionary<string, CachedExpressionItem> CachedExpressionEvaluations { get; }→ wasLazy<>beforeObservableDictionary<string, IBindingProxy> BindingProxies { get; }→ wasLazy<>before
The following properties have been added to the IBasicEntityFlatModel interface:
bool IsCachedExpressionEvaluationsCreated { get; }bool IsBindingProxiesCreated { get; }IReadOnlyCollection<string> GetPropertyNames();— so far only needed when the flat model is used in the entity selection wizard; it should return all property names that should be considered for copying.
CollectionModel
Replace this by subscribing to CollectionModel.Items.CollectionChanged and/or CollectionModel.Items.ListItemChanged. To preserve all notifications handled by the old event, subscribe to both.
These two replacement events also split apart what the old event used to conflate:
CollectionModel.Items.CollectionChangeduses the standardSystem.Collections.Specialized.NotifyCollectionChangedEventArgs/NotifyCollectionChangedAction(e.g.Add,Remove,Reset) — this replaces the old customCollectionChangedEventArgs/eCollectionChangeType(e.g. oldeCollectionChangeType.ItemAdded→ newNotifyCollectionChangedAction.Add).- Item-level property changes, which used to come through the same event as
eCollectionChangeType.PropertyChanged, are now delivered separately viaCollectionModel.Items.ListItemChanged, usingListItemChangedEventArgs(ChangedItem,PropertyName) fromHHDev.Core.NETStandard.Extensions.
If your plugin implements its own IBasicEntityFlatModel (self-implemented flat models, see above), IBindingProxy now needs an explicit using HHDev.Core.NETStandard.Interfaces;.
PayloadProperty
On message payloads (e.g. FlatModelPropertyUpdatedEventArgs.EntityPropertyUpdates), PayloadProperty.Name has been renamed to PayloadProperty.Key.
Ribbon bar tabs
The HHRibbonTab type (previously used via a PluginRibbonTabs property on the plugin entry class) lives in HHDev.Core.Windows, an assembly that is not shipped to plugins. If your plugin declared an unused PluginRibbonTabs property, it can simply be deleted rather than migrated.
View model changes
- IEditViewModel renamed:
- IEditViewModel → IFlatModelEditViewModel
- All custom edit view model implementations must implement
IFlatModelEditViewModelinstead ofIEditViewModel. - The identifier property has been renamed:
FlatModelId→ModelId
EditViewModelManagertype changed:EditViewModelManager<TModel, TViewModel>→FlatModelEditViewModelManager<TModel, TViewModel>- The generic constraint on
TViewModelnow requiresIFlatModelEditViewModelinstead ofIEditViewModel.
Data access changes
-
Accessing data in caches has changed in some cases. There used to be some inconsistency around accessing caches. E.g. the
PartCategoryCacheused to be available via theEventCarMasterCacheas well as theManagementCache. Now it is only available via theManagementCache. -
EventCarMasterCache:- removed
AmbientMeasurementCache(now should be accessed via theEventMasterCache) - removed
PartCache(nowManagementCache.PartCategoryCache) - removed
TyreSpecificationCache(nowManagementCache.TyreSpecificationCache)
- removed
-
A number of cache events named
*Deletedhave been renamed to*Removed, to make naming consistent across all caches. For example:BeforeRunSheetDeleted→BeforeRunSheetRemovedAfterRunSheetDeleted→AfterRunSheetRemovedAfterLapDeleted→AfterLapRemovedAfterAmbientMeasurementDeleted→AfterAmbientMeasurementRemoved
If your plugin subscribes to any cache event ending in
Deleted, check whether it has been renamed to theRemovedequivalent.
Data analysis changes
MathHelpers.ReSampleListAlignedno longer has a 3-argument overload (input, inputFrequency, outputFrequency). Callers must now also passstartTimeanddurationexplicitly (passnullfor either if not needed).LocalDataAnalyser.CalculateAllMathChannelsFromProfile'srequestedChannelsparameter changed from a collection of channel-name strings toIReadOnlyCollection<ChannelModel>, whereChannelModelis a(string Name, eChannelType Type)pair. Callers building this list from channel names will also need to determine the appropriateeChannelTypefor each channel (e.g.Data,Math).- The
Channelsresult ofCalculateAllMathChannelsFromProfileis now typedList<DataViewerChannelProperties>(a subclass ofChannelProperties) rather thanList<ChannelProperties>directly. SinceList<T>isn't covariant in C#, code expectingList<ChannelProperties>will need to convert the result, e.g.result.Channels.Cast<ChannelProperties>().ToList().