TDV - Transfer Drafting Views
TDV (Transfer Drafting Views) is a tool for importing and exporting drafting views between Revit documents and a central library. It enables teams to maintain a shared collection of standard drafting views that can be distributed across projects.
Source:
src/Tools/Common/TDV/manifest.yml:1-45
Overview
TDV provides two primary operations:
- Export to Library - Copy drafting views from the active document to a central library file
- Import from Library - Copy drafting views from a library file to the active document
The tool handles worksharing, creates local copies for edits, and synchronizes changes back to the central library file after export operations.
Source:
src/Tools/Common/TDV/Features/TdvExportCommand.cs:18-27
Features
Core Capabilities
- Bi-directional transfer - Import and export drafting views between documents
- View type mapping - Map source view types to destination view types, or retain original type
- Conflict detection - Real-time detection of naming conflicts with existing views
- Replace mode - Option to replace existing views with the same name
- Preview panel - Live preview of selected drafting views with pan/zoom support
- Batch transfer - Transfer multiple views in a single operation
- Transaction grouping - All transfers wrapped in a transaction group for atomicity
- Progress tracking - Per-view progress feedback during transfer operations
Source:
src/Tools/Common/TDV/Revit/Services/TdvService.cs:106-330
Crash Hardening (2026-02-07)
The TDV import/export apply path was hardened after a Revit 2026 hard-crash investigation:
- Destination-bound transactions - The transfer group and per-view transactions are now started against the explicit destination
Document, not implicitly againstActiveUIDocument. - Cross-document safety checks - TDV now validates that source/destination contexts are valid live documents and not the same document.
- Transfer run diagnostics - Transfer start logs include run id plus source/destination title and path to improve post-crash forensics.
- Non-activating library open - TDV now opens library files with
Application.OpenDocumentFile(...)(no activate) so the host model stays active during transfer and cleanup. - Cleanup-safe close path - TDV commands now use best-effort close (
TryCloseAsync) for library cleanup to prevent cleanup-only close failures from surfacing as command failure banners.
Source:
src/Tools/Common/TDV/Revit/Services/TdvService.cs:106-372Source:src/Tools/Common/TDV/Revit/Services/TdvDocumentService.cs:186-246Source:src/Tools/Common/TDV/Revit/Services/TdvDocumentService.cs:137-168Source:src/Tools/Common/TDV/Features/TdvImportCommand.cs:120-130Source:src/Tools/Common/TDV/Features/TdvExportCommand.cs:143-168Source:src/DBTools.Core/Revit/Transactions/ITransactionGroupService.cs:5-18Source:src/DBTools.Core/Revit/Transactions/CallGateTransactionGroupService.cs:99-280
Library Management
- Multiple library files - Configure multiple library files with fallback paths
- Path validation - Automatic validation of library file accessibility
- Local copy workflow - Creates local copies from central files for worksharing
- Automatic sync - Syncs changes back to central after export with detailed comments
Source:
src/Tools/Common/TDV/Revit/Services/TdvDocumentService.cs:26-126
View Transfer Details
When transferring views, TDV:
- Creates or prepares the destination view with the selected view type
- Copies the view scale and description parameters
- Copies all elements from the source view (excluding viewports, title blocks, schedules, etc.)
- Copies element graphic overrides from source to destination
Source:
src/Tools/Common/TDV/Revit/Services/TdvOps.cs:145-189
View Type Resolution Rules
The row View Type combobox is destination-scoped for the active transfer direction:
- Import (
library -> host): combobox options are drafting view types from the host document. - Export (
host -> library): combobox options are drafting view types from the library document.
Retain Original always resolves to the source view's drafting type name for that row. If that type name is missing in the destination document, TDV creates it by duplicating an existing destination drafting ViewFamilyType and renaming the duplicate.
If source type name resolution fails, TDV records a per-view SourceTypeNameUnavailable error and does not silently fall back.
Source:
src/Tools/Common/TDV/Revit/Services/TdvService.cs:47-95Source:src/Tools/Common/TDV/Revit/Services/TdvService.cs:186-213Source:src/Tools/Common/TDV/Revit/Services/TdvOps.cs:52-99Source:src/Tools/Common/TDV/Revit/Services/TdvOps.cs:233-277
Architecture
TDV follows the MVVM pattern with a clean separation between UI, business logic, and Revit API operations.
Project Structure
src/Tools/Common/TDV/
├── Bootstrap/ # DI registration
├── Contracts/ # Interfaces and DTOs
├── DesignTime/ # Design-time view models
├── Features/ # Command implementations
├── Properties/ # Design-time resources
├── Revit/Services/ # Revit API operations
├── Settings/ # Configuration models
├── Tests/ # Unit tests
└── UI/
├── ViewModels/ # MVVM view models
└── Views/ # WPF views
Service Registration
Services are registered as scoped to properly handle Revit's run-scope dependencies:
Source:
src/Tools/Common/TDV/Bootstrap/TdvServiceExtensions.cs:11-33
services.AddScoped<ITdvTransferService>(sp =>
new TdvService(gate, tx, groups, logger));
services.AddScoped<ITdvLibraryService>(sp =>
new TdvLibraryService(settings, RevitInstanceIdentifier.RevitYear));
services.AddScoped<ITdvDocumentService, TdvDocumentService>();
Key Interfaces
| Interface | Implementation | Purpose |
|---|---|---|
ITdvTransferService |
TdvService |
Core transfer operations |
ITdvLibraryService |
TdvLibraryService |
Library path management |
ITdvDocumentService |
TdvDocumentService |
Document open/close/sync |
ITdvContext |
TdvService.RevitTdvContext |
Abstraction over Revit Document |
Source:
src/Tools/Common/TDV/Contracts/ITdvTransferService.cs:1-23
Transfer Service Operations
The ITdvTransferService interface defines:
| Method | Description |
|---|---|
BuildViewItemsAsync |
Collects drafting views from source document |
ApplySelectionAsync |
Executes the transfer operation |
WouldConflictAsync |
Checks for naming conflicts |
ExportPreviewAsync |
Generates preview image for a view |
Source:
src/Tools/Common/TDV/Contracts/ITdvTransferService.cs:6-22
UI Components
Main Window (TdvWindow)
The main transfer window provides:
- Filter controls - Filter by view type and search by name
- Data grid - Lists all drafting views with transfer options
- Preview panel - Shows selected view with pan/zoom
- Status bar - Displays selection counts and transfer results
Source:
src/Tools/Common/TDV/UI/Views/TdvWindow.xaml:1-537
The TDV window now binds its overlay instance to itself (ProgressOverlayService.For(this)), ensuring overlay ownership and dispatcher affinity are tied to the active TDV host window.
Source:
src/Tools/Common/TDV/UI/Views/TdvWindow.xaml.cs:59-74
ViewModel (TdvWindowViewModel)
Key properties and commands:
| Property | Type | Description |
|---|---|---|
Items |
ObservableCollection<TdvViewItem> |
Filtered list of views |
Search |
string |
Search filter text |
SelectedViewTypeFilter |
string |
View type filter |
SelectedItem |
TdvViewItem |
Currently selected view |
PreviewSource |
ImageSource |
Preview image |
HasAnyConflict |
bool |
Indicates naming conflicts |
Status |
string |
Status bar text |
| Command | Description |
|---|---|
ApplySelectionCommand |
Executes the transfer |
ClearSelectedCommand |
Clears all selections |
ClearSearchCommand |
Clears search filter |
Source:
src/Tools/Common/TDV/UI/ViewModels/TdvWindowViewModel.cs:22-409
View Item (TdvViewItem)
Represents a single drafting view in the UI:
| Property | Type | Description |
|---|---|---|
SourceViewId |
int |
Revit element ID |
ViewName |
string |
Editable view name |
ViewType |
string |
Selected destination type |
ViewTypeName |
string |
Original source type name |
Checked |
bool |
Selected for transfer |
Replace |
bool |
Replace if exists |
HasConflict |
bool |
Has naming conflict |
HasTypeWarning |
bool |
Source type unavailable |
RowState |
string |
Transfer status (pending/success/failure) |
Source:
src/Tools/Common/TDV/UI/ViewModels/TdvViewItem.cs:9-106
Preview Features
The preview panel supports:
- Debounced loading - 200ms debounce prevents excessive exports
- LRU cache - Caches up to 32 preview images
- Pan and zoom - Interactive image manipulation via
ImagePanZoomBehavior - Zoom Extents - Fits + centers the preview image in the viewport
- Best-effort cropping - Preview exports are cropped to content bounds (non-background pixels) so extents-based zoom targets the real view content
- Dark theme background - Consistent preview appearance (RGB: 43, 44, 61)
Source:
src/Tools/Common/TDV/UI/ViewModels/TdvWindowViewModel.cs:74-81Source:src/Tools/Common/TDV/Revit/Services/TdvOps.cs:19-28Source:src/Tools/Common/TDV/UI/Behaviors/TdvImageZoomExtentsBehavior.cs:72Source:src/Tools/Common/TDV/Revit/Services/TdvOps.cs:350
Cache Locations
TDV stores transient files under %APPDATA%\\DBTools\\Cache\\TDV\\:
LibraryLocals\\- Per-operation workshared locals (deleted after the operation closes the library document)Preview\\- Per-window preview export images
Source:
src/Tools/Common/TDV/Services/TdvCachePaths.cs:13Source:src/Tools/Common/TDV/Revit/Services/TdvDocumentService.cs:203Source:src/Tools/Common/TDV/UI/ViewModels/TdvWindowViewModel.cs:446
Settings Configuration
Library Settings
TDV uses the MasterLibrarySettings class to store library file configurations:
public sealed class MasterLibrarySettings
{
public IList<LibraryFileEntry> Files { get; set; }
public bool HasWarnings { get; set; }
}
public sealed class LibraryFileEntry
{
public string? MainPath { get; set; }
public string? FallbackPath { get; set; }
public string? Alias { get; set; }
}
Source:
src/Tools/Common/TDV/Settings/MasterLibrarySettings.cs:1-8Source:src/Tools/Common/TDV/Settings/LibraryFileEntry.cs:1-8
Each library entry supports:
- Main path - Primary path to the library RVT file
- Fallback path - Alternative path (e.g., for different network locations)
- Alias - Optional friendly name used in the Import/Export library picker
Settings Pack
The LibrarySettingsPackContext provides the settings UI with:
- Tree-based library file management
- Add/remove library files
- Add/remove fallback paths
- Real-time path validation
- Pending changes tracking
Source:
src/Tools/Common/TDV/Settings/LibrarySettingsPackContext.cs:19-352
Settings Path Presentation
Library paths in settings are rendered with:
- Validation icon at the left of each tree row (green check / red error)
- Tooltip showing the full absolute path
- Compact display text that keeps root + filename + the final 3 folder levels
This avoids horizontal scrolling while preserving useful location context.
Source:
src/Tools/Common/TDV/Settings/LibrarySettingsPackView.xaml:33-77Source:src/Tools/Common/TDV/Settings/LibrarySettingsPackContext.cs:296-313Source:src/Tools/Common/TDV/Settings/LibraryPathDisplayFormatter.cs:1-63
Path Validation
Library paths are validated for:
- File existence
.rvtextension- Revit version compatibility (file's saved version must match the current Revit session)
- Accessibility
Invalid paths trigger a settings warning that disables the import/export commands.
Source:
src/Tools/Common/TDV/Revit/Services/TdvLibraryService.cs:100-160
Library warnings are evaluated on startup, so the Import/Export ribbon tools may be disabled immediately if configured library paths are invalid.
Source:
src/DBTools.App/Addin/AddinEntry.cs:324Source:src/DBTools.Core/Settings/Features/DbtSettingsStartupWarningEvaluator.cs:36
Revit Version Validation
Library files are checked at two points to prevent version mismatches:
Validation time (
TdvLibraryService.ValidatePath): UsesBasicFileInfo.Extract()andRevitInstanceIdentifier.ParseRevitYear()to compare the file's saved Revit version against the current session. Mismatched files are marked invalid with a descriptive failure reason and excluded from the accessible library list.Open time (
TdvDocumentService.OpenLibraryAsync): A belt-and-suspenders check before opening. ThrowsInvalidOperationExceptionif the file version doesn't match, which is caught by the command's try/catch and displayed as a banner.
This prevents two dangerous scenarios:
- Workshared files:
WorksharingUtils.CreateNewLocal()would throw a version mismatch error at open time - Non-workshared files: Revit would silently upgrade the file, which is destructive
Source:
src/Tools/Common/TDV/Revit/Services/TdvLibraryService.cs:135-155Source:src/Tools/Common/TDV/Revit/Services/TdvDocumentService.cs:30-45
Dialog Suppression During Document Open
When opening a library document, the TDV commands wrap the OpenLibraryAsync call with DialogSuppressionHook.SuppressAvailabilityDialogs(). This suppresses cascading Revit "availability command failed" TaskDialogs (TaskDialog_External_Tools_Command_Failure) that can occur during document switching when Revit re-evaluates IExternalCommandAvailability checks.
The suppression uses a scoped pattern mechanism: a regex pattern is pushed onto a thread-safe stack and automatically removed when the using scope ends.
Limitation: DialogBoxShowing suppression only applies to Revit-hosted dialogs (TaskDialogs and some built-in dialogs). It cannot reliably prevent other add-ins from opening their own WPF/Win32 modal windows during document open/close operations. When third-party modal dialogs block TDV flows, the practical mitigation is to disable the conflicting add-in(s) for that Revit session or expand DialogSuppression patterns for known Revit TaskDialogs.
Source:
src/Tools/Services/DialogSuppression/DialogSuppressionHook.csSource:src/Tools/Common/TDV/Features/TdvImportCommand.cs:92-101Source:src/Tools/Common/TDV/Features/TdvExportCommand.cs:96-105
Manifest Configuration
The tool is configured via manifest.yml:
id: DBTools.TDV
assembly: DBTools
moduleType: DBTools.TDV.TdvToolModule
order: 0
sandboxWindows:
- id: DBTools.TDV.Main
displayName: "Transfer Drafting Views"
group: "Common"
windowType: "DBTools.TDV.UI.Views.TdvWindow"
tool:
settings:
configSection: Core.MasterLibrary
settingsPacks:
- key: core.library
title: "Library Files"
warnings:
- id: core.library.invalid
title: "Library Paths Invalid"
message: "One or more library file paths are invalid..."
disableTools:
- DBTools.ExportToLibrary
- DBTools.ImportFromLibrary
ribbonTools:
- internalName: DBTools.ExportToLibrary
commandType: DBTools.TDV.Features.TdvExportCommand
availabilityType: DBTools.App.Tools.Availability.DbtDocumentAvailability
runProfile: InlineUi
displayText: "Export\nTo Library"
iconBaseKey: export
tooltip: "Export drafting views to the library"
controlKind: StackedButtonItem
splitGroup: library_transfer
- internalName: DBTools.ImportFromLibrary
commandType: DBTools.TDV.Features.TdvImportCommand
availabilityType: DBTools.App.Tools.Availability.DbtDocumentAvailability
runProfile: InlineUi
displayText: "Import\nFrom Library"
iconBaseKey: import
tooltip: "Import drafting views from the library"
controlKind: StackedButtonItem
splitGroup: library_transfer
Source:
src/Tools/Common/TDV/manifest.yml:1-45
Ribbon Configuration
| Property | Export | Import |
|---|---|---|
| Internal Name | DBTools.ExportToLibrary |
DBTools.ImportFromLibrary |
| Command | TdvExportCommand |
TdvImportCommand |
| Run Profile | InlineUi |
InlineUi |
| Icon | export |
import |
| Control Kind | StackedButtonItem |
StackedButtonItem |
| Split Group | library_transfer |
library_transfer |
Error Handling
Per-View Error Codes
Transfer failures are categorized by error code:
| Code | Description |
|---|---|
Unknown |
Unspecified error |
DestinationTypeMissing |
Target view type not found |
SourceTypeNameUnavailable |
Cannot read source view type |
CreateViewFailed |
Failed to create destination view |
CopyElementsFailed |
Failed to copy view elements |
OverridesFailed |
Failed to copy graphic overrides |
Source:
src/Tools/Common/TDV/Contracts/TdvPerViewErrorCode.cs:1-12
Error Reporting
After each transfer attempt, TDV now always surfaces result UX:
- Top banner on the TDV window (
success/warning) with selected/processed/result counts - Summary alert with:
- Selected, processed, added, replaced, and error counts
- Optional per-view issue table when failures exist
- Action buttons: Accept and Transfer More and Close Tool
- Copy-to-clipboard for per-view issue rows
TDV also records and surfaces selection accountability:
- Transfer logs now include selected view identifiers/names (bounded preview)
- Result payload includes
SelectedCount,ProcessedCount, andCancelled - UI warns when selected/processed counts diverge
Source:
src/Tools/Common/TDV/UI/Views/TdvWindow.xaml.cs:111-231Source:src/Tools/Common/TDV/UI/ViewModels/TdvWindowViewModel.cs:274-348Source:src/Tools/Common/TDV/Contracts/TdvApplySelectionResult.cs:5-13Source:src/Tools/Common/TDV/Revit/Services/TdvService.cs:125-372
Revit API Operations
Getting Drafting Views
new FilteredElementCollector(doc)
.OfClass(typeof(View))
.WhereElementIsNotElementType()
.Cast<View>()
.Where(v => v.ViewType == ViewType.DraftingView && !v.IsTemplate)
Source:
src/Tools/Common/TDV/Revit/Services/TdvOps.cs:30-39
Copying View Contents
Elements are copied using ElementTransformUtils.CopyElements with a custom IDuplicateTypeNamesHandler that uses destination types when duplicates are found.
Source:
src/Tools/Common/TDV/Revit/Services/TdvOps.cs:145-162
Skipped Categories
The following categories are excluded from copy operations:
- Title Blocks
- Viewports
- Views
- Schedules
- Guide Grids
Source:
src/Tools/Common/TDV/Revit/Services/TdvOps.cs:13-16
Command Reference
Library Selection Dialog Sizing
TDV export/import library selection dialogs override default alert dimensions to a compact tool-specific size:
- Width:
640 - Height:
420 - MinWidth:
520 - MinHeight:
340
Source:
src/Tools/Common/TDV/Features/TdvAlertWindowOptions.cs:1-17Source:src/Tools/Common/TDV/Features/TdvExportCommand.cs:75-84Source:src/Tools/Common/TDV/Features/TdvImportCommand.cs:70-79
Library Picker Display
The library picker list uses:
- Alias (when configured) for a short readable name
- A compact tail-of-path suffix when no alias is present (keeps the dialog narrow without losing location context)
Source:
src/Tools/Common/TDV/Features/TdvImportCommand.cs:70Source:src/Tools/Common/TDV/Features/TdvExportCommand.cs:75Source:src/Tools/Common/TDV/Settings/LibraryPathDisplayFormatter.cs:8
Export Command Flow
- Validate library paths are configured
- Prompt user to select a library file
- If workshared, create a per-operation local copy under the TDV cache folder
- Open library document
- Show TdvWindow for view selection
- Execute transfer to library
- Sync changes to central with comment
- Close library and reactivate original document
Source:
src/Tools/Common/TDV/Features/TdvExportCommand.cs:31-137
Import Command Flow
- Validate library paths are configured
- Prompt user to select a library file
- If workshared, create a per-operation local copy under the TDV cache folder
- Open library document
- Show TdvWindow for view selection
- Execute transfer to active document
- Close library (no sync needed)
Source:
src/Tools/Common/TDV/Features/TdvImportCommand.cs:27-107
Cross-References
- Architecture Overview - Application architecture patterns
- App Project - Main application and tool hosting
Testing
TDV includes unit tests for:
TdvViewItem- View model behaviorTdvLibraryService- Path validation and library managementTdvAdapter- Service adapter tests
Source:
src/Tools/Common/TDV/Tests/
Last updated: March 2026