View Template Comparer (VTC) — Developer Guide
VTC is a testing tool for side-by-side view-template comparison with staged local edits and a single Process execution path.
See also: VTC internal design notes.
Current Architecture
Command + window
VtcCommandis the Revit command entrypoint.VtcCommandHandlerbuilds document-scoped services and constructsVtcWindowViewModel.VtcWindowis the shell view; Process/Preview UX is driven from VM + XAML templates.
Source:
src/Tools/Testing/VTC/Features/VtcCommand.cs:14Source:src/Tools/Testing/VTC/Features/VtcCommandHandler.cs:48Source:src/Tools/Testing/VTC/UI/Views/VtcWindow.xaml:1
Core services
IVtcComparisonServicecompares/extracts and now providesBatchApply(...).IVtcSerializationServicenow only supportsCreateTemplateFromModel+ApplyModel.IVtcTemplateStorageServiceremains the cache Save/Load surface.
Source:
src/Tools/Testing/VTC/Contracts/IVtcComparisonService.cs:24Source:src/Tools/Testing/VTC/Contracts/IVtcSerializationService.cs:6Source:src/Tools/Testing/VTC/Services/VtcTemplateStorageService.cs:203
REV2 Data Contracts
Added contracts used by Process + Preview:
VtcOutputModeVtcPendingOverride(usesEditedSide)VtcProcessResultVtcPreviewItem- UI-local preview hierarchy node:
VtcPreviewTreeNode
Source:
src/Tools/Testing/VTC/Contracts/VtcEnums.cs:206Source:src/Tools/Testing/VTC/Contracts/VtcDataModels.cs:224Source:src/Tools/Testing/VTC/Contracts/VtcDataModels.cs:233Source:src/Tools/Testing/VTC/Contracts/VtcDataModels.cs:238Source:src/Tools/Testing/VTC/UI/ViewModels/VtcWindowViewModel.cs:2142
Process Flow (REV2)
Dialog body + validity gating
VtcProcessDialogBodyViewModel implements IAlertBody and raises ValidityChanged when OutputMode or NewTemplateName changes, enabling DisableWhenInvalid button gating.
Radio bindings use VtcEnumToBoolConverter.
Read-only Process counters in VtcBodyTemplates.xaml are explicitly bound Mode=OneWay to avoid WPF attempting TwoWay updates on read-only VM properties.
Source:
src/Tools/Testing/VTC/UI/ViewModels/VtcProcessDialogBodyViewModel.cs:13Source:src/Tools/Testing/VTC/UI/ViewModels/VtcProcessDialogBodyViewModel.cs:70Source:src/Tools/Testing/VTC/UI/Resources/VtcBodyTemplates.xaml:354Source:src/Tools/Testing/VTC/UI/ViewModels/VtcWindowViewModel.cs:601
VM execution semantics
Process()builds preview and opens Process dialog.ExecuteProcess(...)handles overwrite-left, overwrite-right, and create-merged.- Pending overrides are applied only when selected side matches pending edited side.
- Process command gating now requires
HasSelections || HasProcessablePendingOverrides(prevents no-op Process when staged edits exist but are ineligible). - Create-merged model merge removes base-side keyed list items when the user selected the opposite side and that keyed item is missing there (preserves LeftMissing/RightMissing selection intent).
- During ApplySnapshot, missing-side selections for category/workset/link now clear/reset base-side override state instead of no-op preserving base values.
- Success clears pending/local edits and rebuilds comparison.
- Process conflicts preserve failed pending overrides by restoring them after rebuild for retry.
Source:
src/Tools/Testing/VTC/UI/ViewModels/VtcWindowViewModel.cs:563Source:src/Tools/Testing/VTC/UI/ViewModels/VtcWindowViewModel.cs:1511Source:src/Tools/Testing/VTC/UI/ViewModels/VtcWindowViewModel.cs:1620Source:src/Tools/Testing/VTC/UI/ViewModels/VtcWindowViewModel.cs:1940Source:src/Tools/Testing/VTC/UI/ViewModels/VtcWindowViewModel.cs:1766Source:src/Tools/Testing/VTC/UI/ViewModels/VtcWindowViewModel.cs:1898Source:src/Tools/Testing/VTC/Revit/Services/VtcComparisonService.cs:376Source:src/Tools/Testing/VTC/Revit/Services/VtcComparisonService.cs:1395Source:src/Tools/Testing/VTC/Revit/Services/VtcComparisonService.cs:1694
Batch apply behavior
VtcComparisonService.BatchApply(...) runs all selected changes + eligible pending overrides in one parent transaction. Each individual selection/pending-override apply runs in its own SubTransaction; expected per-setting failures are captured as conflicts and rolled back so failed keys do not leave partial writes. Unexpected exceptions still propagate.
Source:
src/Tools/Testing/VTC/Revit/Services/VtcComparisonService.cs:98Source:src/Tools/Testing/VTC/Revit/Services/VtcComparisonService.cs:120Source:src/Tools/Testing/VTC/Revit/Services/VtcComparisonService.cs:163Source:src/Tools/Testing/VTC/Revit/Services/VtcComparisonService.cs:187
Local Override Model
VtcDiffTreeNode owns local override state on canonical nodes (OriginalNode ?? this) so filtered proxy nodes remain consistent.
- Local writes:
SetLocalOverrideData(...) - Local reads:
GetCategoryDataForSide(...) - Inline displays:
LeftCategoryData/RightCategoryData - Side-specific local-state flags:
HasLocalOverrideLeft/HasLocalOverrideRight - Per-side and all-side clear APIs
Source:
src/Tools/Testing/VTC/UI/ViewModels/VtcDiffTreeNode.cs:213Source:src/Tools/Testing/VTC/UI/ViewModels/VtcDiffTreeNode.cs:253Source:src/Tools/Testing/VTC/UI/ViewModels/VtcDiffTreeNode.cs:261Source:src/Tools/Testing/VTC/UI/ViewModels/VtcDiffTreeNode.cs:278Source:src/Tools/Testing/VTC/UI/ViewModels/VtcDiffTreeNode.cs:247
Pending Override Lifecycle Rules
Implemented behavior:
- Pending overrides tracked by key in VM.
- Any rebuild/pairing swap clears pending/local edits with explicit notice.
- Selection-side flip for a key invalidates pending/local state for that key, but
SelectedSide=Noneno longer purges staged edits. - Failed pending overrides from Process conflicts are restored after rebuild and remain retry-eligible even if their diff row no longer exists.
- Preview rows/tree are backed by indexed key lookup (
_nodeByKeyIndex) rebuilt with tree rebuilds. - Preview pending count uses Process eligibility (
GetEligiblePendingOverrides) so Preview reflects what Process will attempt.
Source:
src/Tools/Testing/VTC/UI/ViewModels/VtcWindowViewModel.cs:46Source:src/Tools/Testing/VTC/UI/ViewModels/VtcWindowViewModel.cs:541Source:src/Tools/Testing/VTC/UI/ViewModels/VtcWindowViewModel.cs:1546Source:src/Tools/Testing/VTC/UI/ViewModels/VtcWindowViewModel.cs:1766Source:src/Tools/Testing/VTC/UI/ViewModels/VtcWindowViewModel.cs:1898Source:src/Tools/Testing/VTC/UI/ViewModels/VtcWindowViewModel.cs:398
UI Composition (REV2)
Right-side tabs and footer
- Inspector + Preview + Library tabs
- Inspector now exposes explicit per-row side actions (
Use Left,Use Right,Clear) and per-side override edit actions (Edit Left,Edit Right). - Tree rows expose per-side inline edit buttons so edit intent is separate from selection intent.
- Library save menu now includes Left/Right/Merged save targets (
SaveMergedTemplateCommandpersists a merged model built from selections + eligible pending overrides) - BottomPanel footer with
CloseandProcess
Source:
src/Tools/Testing/VTC/UI/Views/VtcWindow.xaml:1123Source:src/Tools/Testing/VTC/UI/Views/VtcWindow.xaml:317Source:src/Tools/Testing/VTC/UI/Views/VtcWindow.xaml:1297Source:src/Tools/Testing/VTC/UI/Views/VtcWindow.xaml:1244Source:src/Tools/Testing/VTC/UI/Views/VtcWindow.xaml:1267Source:src/Tools/Testing/VTC/UI/ViewModels/VtcWindowViewModel.cs:1365Source:src/Tools/Testing/VTC/UI/ViewModels/VtcWindowViewModel.cs:1687Source:src/Tools/Testing/VTC/UI/ViewModels/VtcWindowViewModel.cs:2089Source:src/Tools/Testing/VTC/UI/Views/VtcWindow.xaml:1330
Preview navigation contract
Preview uses a dedicated hierarchy (PreviewTreeRoots) rendered in a TreeView. Preview selection uses OnPreviewTreeItemSelected to call shared navigation logic (NavigateToPreviewSetting) that will:
- clear search/filter state,
- select target node,
- expand only the target ancestor path and
BringIntoViewthe realizedTreeViewItem.
Source:
src/Tools/Testing/VTC/UI/Views/VtcWindow.xaml:1241Source:src/Tools/Testing/VTC/UI/ViewModels/VtcWindowViewModel.cs:458Source:src/Tools/Testing/VTC/UI/ViewModels/VtcWindowViewModel.cs:1943Source:src/Tools/Testing/VTC/UI/Views/VtcWindow.xaml.cs:139Source:src/Tools/Testing/VTC/UI/Views/VtcWindow.xaml.cs:153
Selection visual contract
- Gold border/checkmark/glow represent selection.
- Manual staged overrides now use an explicit
Editedbadge with side-colored dots in TreeView, Inspector, and Preview. - Hover emphasis preserves existing diff tint and uses typography emphasis (no dark hover fill on diff cells).
- Storyboard uses
(UIElement.Effect).(DropShadowEffect.Opacity). - Effect instance uses
x:Shared="False"resource (VtcSelectionGlowEffect) to keep animations valid per cell. - Conflict visuals override selection visuals.
Source:
src/Tools/Testing/VTC/UI/Resources/VtcDiffStyles.xaml:12Source:src/Tools/Testing/VTC/UI/Resources/VtcDiffStyles.xaml:51Source:src/Tools/Testing/VTC/UI/Views/VtcWindow.xaml:276Source:src/Tools/Testing/VTC/UI/Views/VtcWindow.xaml:687Source:src/Tools/Testing/VTC/UI/Resources/VtcDiffStyles.xaml:475Source:src/Tools/Testing/VTC/UI/Resources/VtcDiffStyles.xaml:507
Design-time preview contract
VtcWindowXAML declares a design-time instance ofVtcWindowDesignTimeViewModel.- Non-design runtime construction stays constructor-injected, while sandbox fallback still uses the design-time VM.
- The design-time VM now mirrors the live window binding surface used by the REV2 shell (tree/filter/inspector/library/link commands) and seeds representative REV2 tab/tree data.
Source:
src/Tools/Testing/VTC/UI/Views/VtcWindow.xaml:14Source:src/Tools/Testing/VTC/UI/Views/VtcWindow.xaml.cs:31Source:src/Tools/Testing/VTC/DesignTime/VtcWindowDesignTimeViewModel.cs:27Source:src/Tools/Testing/VTC/DesignTime/VtcWindowDesignTimeViewModel.cs:83Source:src/Tools/Testing/VTC/DesignTime/VtcWindowDesignTimeViewModel.cs:160
Removed/Retired Paths
The REV2 implementation removes legacy VTC transfer/apply surfaces:
IVtcDumpService/VtcDumpService- serialization
Export/Import - VM Export/Import/Dump/Merge-to-new/apply-to-left-right command paths
- legacy floating apply bar and transfer/create-merged library sections
Source:
src/Tools/Testing/VTC/Contracts/IVtcSerializationService.cs:6Source:src/Tools/Testing/VTC/Revit/Services/VtcSerializationService.cs:30Source:src/Tools/Testing/VTC/UI/ViewModels/VtcWindowViewModel.cs:563Source:src/Tools/Testing/VTC/UI/Views/VtcWindow.xaml:1244
Tests
VtcWindowViewModelTests now validates local staging, idempotent same-side selection, side-specific override editing, clear-selection pending-retention semantics, Process gating for ineligible pending edits, Process overwrite/create-merged flows, conflict marker mapping, failed-pending-override retention after Process conflicts, and merged-save model generation for missing-side and pending-override scenarios.
Source:
src/Tools/Testing/VTC/Tests/VtcWindowViewModelTests.cs:38Source:src/Tools/Testing/VTC/Tests/VtcWindowViewModelTests.cs:79Source:src/Tools/Testing/VTC/Tests/VtcWindowViewModelTests.cs:92Source:src/Tools/Testing/VTC/Tests/VtcWindowViewModelTests.cs:127Source:src/Tools/Testing/VTC/Tests/VtcWindowViewModelTests.cs:262Source:src/Tools/Testing/VTC/Tests/VtcWindowViewModelTests.cs:347