├── source
├── Nice3point.Revit.AddIn
│ ├── Models
│ │ └── keep.folder
│ ├── Resources
│ │ ├── keep.folder
│ │ └── Icons
│ │ │ ├── RibbonIcon16.png
│ │ │ └── RibbonIcon32.png
│ ├── Views
│ │ ├── Nice3point.Revit.AddInView.xaml.cs
│ │ ├── Converters
│ │ │ ├── InverseBooleanConverter.cs
│ │ │ ├── BooleanHiddenVisibilityConverter.cs
│ │ │ ├── BooleanCollapsedVisibilityConverter.cs
│ │ │ ├── InverseBooleanHiddenVisibilityConverter.cs
│ │ │ ├── InverseBooleanCollapsedVisibilityConverter.cs
│ │ │ ├── EmptyCollectionVisibilityConverter.cs
│ │ │ ├── InverseEmptyCollectionVisibilityConverter.cs
│ │ │ ├── EmptyCollectionsVisibilityConverter.cs
│ │ │ ├── InverseEmptyCollectionsVisibilityConverter.cs
│ │ │ ├── EnumHiddenVisibilityConverter.cs
│ │ │ ├── EnumCollapsedVisibilityConverter.cs
│ │ │ ├── EnumBooleanConverter.cs
│ │ │ └── StringVisibilityConverter.cs
│ │ └── Nice3point.Revit.AddInView.xaml
│ ├── Config
│ │ ├── Options
│ │ │ └── ApplicationOptions.cs
│ │ └── Logging
│ │ │ └── LoggerConfiguration.cs
│ ├── ViewModels
│ │ └── Nice3point.Revit.AddInViewModel.cs
│ ├── Nice3point.Revit.AddIn.addin
│ ├── Application.cs
│ └── Commands
│ │ └── StartupCommand.cs
├── Nice3point.Revit.AddIn.Module
│ ├── Models
│ │ └── keep.folder
│ ├── ViewModels
│ │ └── Nice3point.Revit.AddInViewModel.cs
│ ├── Views
│ │ ├── Nice3point.Revit.AddInView.xaml.cs
│ │ ├── Converters
│ │ │ ├── InverseBooleanConverter.cs
│ │ │ ├── BooleanHiddenVisibilityConverter.cs
│ │ │ ├── BooleanCollapsedVisibilityConverter.cs
│ │ │ ├── InverseBooleanHiddenVisibilityConverter.cs
│ │ │ ├── InverseBooleanCollapsedVisibilityConverter.cs
│ │ │ ├── EmptyCollectionVisibilityConverter.cs
│ │ │ ├── InverseEmptyCollectionVisibilityConverter.cs
│ │ │ ├── EmptyCollectionsVisibilityConverter.cs
│ │ │ ├── InverseEmptyCollectionsVisibilityConverter.cs
│ │ │ ├── EnumHiddenVisibilityConverter.cs
│ │ │ ├── EnumCollapsedVisibilityConverter.cs
│ │ │ ├── EnumBooleanConverter.cs
│ │ │ └── StringVisibilityConverter.cs
│ │ └── Nice3point.Revit.AddInView.xaml
│ ├── .template.config
│ │ └── template.json
│ └── Nice3point.Revit.AddIn.csproj
├── Nice3point.Revit.AddIn.Solution
│ ├── source
│ │ └── keep.folder
│ ├── Changelog.md
│ ├── .nuke
│ │ ├── build.cmd
│ │ └── parameters.json
│ ├── global.json
│ ├── install
│ │ ├── Resources
│ │ │ └── Icons
│ │ │ │ ├── ShellIcon.ico
│ │ │ │ ├── BannerImage.png
│ │ │ │ └── BackgroundImage.png
│ │ ├── Installer.csproj
│ │ ├── Installer.cs
│ │ └── Installer.Generator.cs
│ ├── .gitignore
│ ├── .github
│ │ └── workflows
│ │ │ ├── Compile.yml
│ │ │ └── PublishRelease.yml
│ ├── build
│ │ ├── .editorconfig
│ │ ├── Build.Publish.Clean.cs
│ │ ├── Build.Regex.cs
│ │ ├── Build.Compile.cs
│ │ ├── Build.csproj
│ │ ├── Build.cs
│ │ ├── Build.Clean.cs
│ │ ├── Build.Publish.GitHub.cs
│ │ ├── Build.Changelog.cs
│ │ └── Build.CreateInstaller.cs
│ ├── .run
│ │ ├── Nuke.run.xml
│ │ ├── Nuke Plan.run.xml
│ │ └── Nuke Clean.run.xml
│ └── azure-pipelines.yml
├── Nice3point.Revit.AddIn.Application
│ ├── Resources
│ │ ├── keep.folder
│ │ └── Icons
│ │ │ ├── RibbonIcon16.png
│ │ │ └── RibbonIcon32.png
│ ├── Commands
│ │ └── StartupCommand.cs
│ ├── Config
│ │ ├── Options
│ │ │ └── ApplicationOptions.cs
│ │ └── Logging
│ │ │ └── LoggerConfiguration.cs
│ ├── Nice3point.Revit.AddIn.addin
│ ├── Application.cs
│ └── Host.cs
└── RevitTemplates.csproj
├── .github
├── FUNDING.yml
└── workflows
│ └── Publish Release.yml
├── samples
├── MultiProjectSolution
│ ├── Changelog.md
│ ├── .nuke
│ │ ├── build.cmd
│ │ ├── parameters.json
│ │ └── build.ps1
│ ├── global.json
│ ├── install
│ │ ├── Resources
│ │ │ └── Icons
│ │ │ │ ├── ShellIcon.ico
│ │ │ │ ├── BannerImage.png
│ │ │ │ └── BackgroundImage.png
│ │ ├── Installer.csproj
│ │ ├── Installer.cs
│ │ └── Installer.Generator.cs
│ ├── source
│ │ ├── RevitAddIn
│ │ │ ├── Resources
│ │ │ │ └── Icons
│ │ │ │ │ ├── RibbonIcon16.png
│ │ │ │ │ └── RibbonIcon32.png
│ │ │ ├── RevitAddIn.addin
│ │ │ ├── Commands
│ │ │ │ ├── ShowModalWindowCommand.cs
│ │ │ │ └── ShowModelessWindowCommand.cs
│ │ │ ├── Config
│ │ │ │ ├── SerializerConfiguration.cs
│ │ │ │ └── LoggerConfigurator.cs
│ │ │ ├── Application.cs
│ │ │ └── Host.cs
│ │ ├── ModalModule
│ │ │ ├── Views
│ │ │ │ ├── ModalModuleView.xaml.cs
│ │ │ │ └── ModalModuleView.xaml
│ │ │ ├── ViewModels
│ │ │ │ └── ModalModuleViewModel.cs
│ │ │ └── ModalModule.csproj
│ │ └── ModelessModule
│ │ │ ├── Views
│ │ │ ├── ModelessModuleView.xaml.cs
│ │ │ └── ModelessModuleView.xaml
│ │ │ ├── Services
│ │ │ └── ModelessController.cs
│ │ │ └── ModelessModule.csproj
│ ├── .gitignore
│ ├── .github
│ │ └── workflows
│ │ │ ├── Compile.yml
│ │ │ └── PublishRelease.yml
│ ├── build
│ │ ├── Build.Regex.cs
│ │ ├── .editorconfig
│ │ ├── Build.Publish.Clean.cs
│ │ ├── Build.Compile.cs
│ │ ├── Build.csproj
│ │ ├── Build.cs
│ │ ├── Build.Clean.cs
│ │ ├── Build.Publish.GitHub.cs
│ │ ├── Build.Changelog.cs
│ │ └── Build.CreateInstaller.cs
│ └── .run
│ │ ├── Nuke.run.xml
│ │ ├── Nuke Plan.run.xml
│ │ └── Nuke Clean.run.xml
├── MultiProjectApplication
│ ├── Module3
│ │ ├── Enums
│ │ │ └── EntryKey.cs
│ │ ├── Schemas
│ │ │ └── ProjectInfoSchema.cs
│ │ └── Module3.csproj
│ ├── RevitAddIn
│ │ ├── Resources
│ │ │ └── Icons
│ │ │ │ ├── RibbonIcon16.png
│ │ │ │ └── RibbonIcon32.png
│ │ ├── RevitAddIn.addin
│ │ ├── Commands
│ │ │ ├── Module1StartupCommand.cs
│ │ │ └── Module2StartupCommand.cs
│ │ └── Application.cs
│ ├── Module1
│ │ ├── Views
│ │ │ ├── Module1View.xaml.cs
│ │ │ └── Module1View.xaml
│ │ ├── ViewModels
│ │ │ └── Module1ViewModel.cs
│ │ └── Module1.csproj
│ └── Module2
│ │ ├── Views
│ │ ├── Module2View.xaml.cs
│ │ └── Module2View.xaml
│ │ ├── ViewModels
│ │ └── Module2ViewModel.cs
│ │ └── Module2.csproj
├── SingleProjectApplication
│ ├── RevitAddIn
│ │ ├── Resources
│ │ │ └── Icons
│ │ │ │ ├── RibbonIcon16.png
│ │ │ │ └── RibbonIcon32.png
│ │ ├── RevitAddIn.addin
│ │ ├── Application.cs
│ │ ├── Commands
│ │ │ └── StartupCommand.cs
│ │ └── RevitAddIn.csproj
│ └── SingleProjectApplication.sln
├── SingleProjectDIApplication
│ └── RevitAddIn
│ │ ├── Resources
│ │ └── Icons
│ │ │ ├── RibbonIcon16.png
│ │ │ └── RibbonIcon32.png
│ │ ├── Views
│ │ ├── RevitAddInView.xaml.cs
│ │ └── RevitAddInView.xaml
│ │ ├── RevitAddIn.addin
│ │ ├── Commands
│ │ └── StartupCommand.cs
│ │ ├── ViewModels
│ │ └── RevitAddInViewModel.cs
│ │ ├── Application.cs
│ │ └── Host.cs
├── SingleProjectHostingApplication
│ └── RevitAddIn
│ │ ├── Resources
│ │ └── Icons
│ │ │ ├── RibbonIcon16.png
│ │ │ └── RibbonIcon32.png
│ │ ├── Views
│ │ ├── RevitAddInView.xaml.cs
│ │ └── RevitAddInView.xaml
│ │ ├── RevitAddIn.addin
│ │ ├── Commands
│ │ └── StartupCommand.cs
│ │ ├── ViewModels
│ │ └── RevitAddInViewModel.cs
│ │ ├── Application.cs
│ │ └── Host.cs
├── SingleProjectWpfModalApplication
│ └── RevitAddIn
│ │ ├── Resources
│ │ └── Icons
│ │ │ ├── RibbonIcon16.png
│ │ │ └── RibbonIcon32.png
│ │ ├── Views
│ │ ├── RevitAddInView.xaml.cs
│ │ └── RevitAddInView.xaml
│ │ ├── RevitAddIn.addin
│ │ ├── Commands
│ │ └── StartupCommand.cs
│ │ ├── Application.cs
│ │ └── ViewModels
│ │ └── RevitAddInViewModel.cs
└── SingleProjectWpfModelessApplication
│ └── RevitAddIn
│ ├── Resources
│ └── Icons
│ │ ├── RibbonIcon16.png
│ │ └── RibbonIcon32.png
│ ├── Views
│ ├── RevitAddinView.xaml.cs
│ └── RevitAddinView.xaml
│ ├── RevitAddin.addin
│ ├── Application.cs
│ ├── Commands
│ └── StartupCommand.cs
│ └── ViewModels
│ └── RevitAddinViewModel.cs
├── .nuke
├── Build.cmd
├── parameters.json
└── Build.ps1
├── .nuget
└── PackageIcon.png
├── global.json
├── renovate.json
├── .gitignore
├── Contributing.md
├── .run
├── Nuke.run.xml
├── Nuke Plan.run.xml
└── Nuke Clean.run.xml
├── License.md
├── RevitTemplates.sln
└── Readme.md
/source/Nice3point.Revit.AddIn/Models/keep.folder:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | custom: github.com/Atomatiq
2 |
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn/Resources/keep.folder:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Module/Models/keep.folder:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Solution/source/keep.folder:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Application/Resources/keep.folder:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/Changelog.md:
--------------------------------------------------------------------------------
1 | # 1.0.0
2 |
3 | Initial release. Enjoy!
--------------------------------------------------------------------------------
/.nuke/Build.cmd:
--------------------------------------------------------------------------------
1 | powershell -ExecutionPolicy ByPass -NoProfile -File "%~dp0Build.ps1" %*
2 |
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Solution/Changelog.md:
--------------------------------------------------------------------------------
1 | # 1.0.0
2 |
3 | Initial release. Enjoy!
--------------------------------------------------------------------------------
/.nuget/PackageIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nice3point/RevitTemplates/HEAD/.nuget/PackageIcon.png
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/.nuke/build.cmd:
--------------------------------------------------------------------------------
1 | powershell -ExecutionPolicy ByPass -NoProfile -File "%~dp0Build.ps1" %*
2 |
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Solution/.nuke/build.cmd:
--------------------------------------------------------------------------------
1 | powershell -ExecutionPolicy ByPass -NoProfile -File "%~dp0Build.ps1" %*
2 |
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "sdk": {
3 | "version": "9.0.0",
4 | "rollForward": "latestMinor"
5 | }
6 | }
--------------------------------------------------------------------------------
/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "sdk": {
3 | "version": "9.0.0",
4 | "rollForward": "latestMinor",
5 | "allowPrerelease": false
6 | }
7 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Solution/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "sdk": {
3 | "version": "9.0.0",
4 | "rollForward": "latestMinor"
5 | }
6 | }
--------------------------------------------------------------------------------
/samples/MultiProjectApplication/Module3/Enums/EntryKey.cs:
--------------------------------------------------------------------------------
1 | namespace Module3.Enums;
2 |
3 | public enum EntryKey
4 | {
5 | Data,
6 | Secrets
7 | }
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "baseBranchPatterns": ["develop"],
4 | "ignorePaths": ["global.json"]
5 | }
6 |
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/.nuke/parameters.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./build.schema.json",
3 | "Solution": "MultiProjectSolution.sln",
4 | "Verbosity": "Normal"
5 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Solution/.nuke/parameters.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./build.schema.json",
3 | "Solution": "Nice3point.Revit.AddIn.sln",
4 | "Verbosity": "Normal"
5 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn/Resources/Icons/RibbonIcon16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nice3point/RevitTemplates/HEAD/source/Nice3point.Revit.AddIn/Resources/Icons/RibbonIcon16.png
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn/Resources/Icons/RibbonIcon32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nice3point/RevitTemplates/HEAD/source/Nice3point.Revit.AddIn/Resources/Icons/RibbonIcon32.png
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/install/Resources/Icons/ShellIcon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nice3point/RevitTemplates/HEAD/samples/MultiProjectSolution/install/Resources/Icons/ShellIcon.ico
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/install/Resources/Icons/BannerImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nice3point/RevitTemplates/HEAD/samples/MultiProjectSolution/install/Resources/Icons/BannerImage.png
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/install/Resources/Icons/BackgroundImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nice3point/RevitTemplates/HEAD/samples/MultiProjectSolution/install/Resources/Icons/BackgroundImage.png
--------------------------------------------------------------------------------
/samples/MultiProjectApplication/RevitAddIn/Resources/Icons/RibbonIcon16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nice3point/RevitTemplates/HEAD/samples/MultiProjectApplication/RevitAddIn/Resources/Icons/RibbonIcon16.png
--------------------------------------------------------------------------------
/samples/MultiProjectApplication/RevitAddIn/Resources/Icons/RibbonIcon32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nice3point/RevitTemplates/HEAD/samples/MultiProjectApplication/RevitAddIn/Resources/Icons/RibbonIcon32.png
--------------------------------------------------------------------------------
/samples/SingleProjectApplication/RevitAddIn/Resources/Icons/RibbonIcon16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nice3point/RevitTemplates/HEAD/samples/SingleProjectApplication/RevitAddIn/Resources/Icons/RibbonIcon16.png
--------------------------------------------------------------------------------
/samples/SingleProjectApplication/RevitAddIn/Resources/Icons/RibbonIcon32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nice3point/RevitTemplates/HEAD/samples/SingleProjectApplication/RevitAddIn/Resources/Icons/RibbonIcon32.png
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Application/Resources/Icons/RibbonIcon16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nice3point/RevitTemplates/HEAD/source/Nice3point.Revit.AddIn.Application/Resources/Icons/RibbonIcon16.png
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Application/Resources/Icons/RibbonIcon32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nice3point/RevitTemplates/HEAD/source/Nice3point.Revit.AddIn.Application/Resources/Icons/RibbonIcon32.png
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Solution/install/Resources/Icons/ShellIcon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nice3point/RevitTemplates/HEAD/source/Nice3point.Revit.AddIn.Solution/install/Resources/Icons/ShellIcon.ico
--------------------------------------------------------------------------------
/samples/SingleProjectDIApplication/RevitAddIn/Resources/Icons/RibbonIcon16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nice3point/RevitTemplates/HEAD/samples/SingleProjectDIApplication/RevitAddIn/Resources/Icons/RibbonIcon16.png
--------------------------------------------------------------------------------
/samples/SingleProjectDIApplication/RevitAddIn/Resources/Icons/RibbonIcon32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nice3point/RevitTemplates/HEAD/samples/SingleProjectDIApplication/RevitAddIn/Resources/Icons/RibbonIcon32.png
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Module/ViewModels/Nice3point.Revit.AddInViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace Nice3point.Revit.AddIn.ViewModels;
2 |
3 | public sealed class Nice3point.Revit.AddInViewModel : ObservableObject
4 | {
5 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Solution/install/Resources/Icons/BannerImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nice3point/RevitTemplates/HEAD/source/Nice3point.Revit.AddIn.Solution/install/Resources/Icons/BannerImage.png
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/source/RevitAddIn/Resources/Icons/RibbonIcon16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nice3point/RevitTemplates/HEAD/samples/MultiProjectSolution/source/RevitAddIn/Resources/Icons/RibbonIcon16.png
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/source/RevitAddIn/Resources/Icons/RibbonIcon32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nice3point/RevitTemplates/HEAD/samples/MultiProjectSolution/source/RevitAddIn/Resources/Icons/RibbonIcon32.png
--------------------------------------------------------------------------------
/samples/SingleProjectHostingApplication/RevitAddIn/Resources/Icons/RibbonIcon16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nice3point/RevitTemplates/HEAD/samples/SingleProjectHostingApplication/RevitAddIn/Resources/Icons/RibbonIcon16.png
--------------------------------------------------------------------------------
/samples/SingleProjectHostingApplication/RevitAddIn/Resources/Icons/RibbonIcon32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nice3point/RevitTemplates/HEAD/samples/SingleProjectHostingApplication/RevitAddIn/Resources/Icons/RibbonIcon32.png
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Solution/install/Resources/Icons/BackgroundImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nice3point/RevitTemplates/HEAD/source/Nice3point.Revit.AddIn.Solution/install/Resources/Icons/BackgroundImage.png
--------------------------------------------------------------------------------
/.nuke/parameters.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./build.schema.json",
3 | "Solution": "RevitTemplates.sln",
4 | "Verbosity": "Normal",
5 | "NugetApiKey": "v1:FKm1A4E2Cl3jNhUB5IFCOYoMOOqpLrGu7wM4socot+KVrRkSck/W3m8OM42Z/nIb"
6 | }
7 |
--------------------------------------------------------------------------------
/samples/SingleProjectWpfModalApplication/RevitAddIn/Resources/Icons/RibbonIcon16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nice3point/RevitTemplates/HEAD/samples/SingleProjectWpfModalApplication/RevitAddIn/Resources/Icons/RibbonIcon16.png
--------------------------------------------------------------------------------
/samples/SingleProjectWpfModalApplication/RevitAddIn/Resources/Icons/RibbonIcon32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nice3point/RevitTemplates/HEAD/samples/SingleProjectWpfModalApplication/RevitAddIn/Resources/Icons/RibbonIcon32.png
--------------------------------------------------------------------------------
/samples/SingleProjectWpfModelessApplication/RevitAddIn/Resources/Icons/RibbonIcon16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nice3point/RevitTemplates/HEAD/samples/SingleProjectWpfModelessApplication/RevitAddIn/Resources/Icons/RibbonIcon16.png
--------------------------------------------------------------------------------
/samples/SingleProjectWpfModelessApplication/RevitAddIn/Resources/Icons/RibbonIcon32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nice3point/RevitTemplates/HEAD/samples/SingleProjectWpfModelessApplication/RevitAddIn/Resources/Icons/RibbonIcon32.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #IDE folders
2 | *.idea/
3 | *.vs/
4 | *.vscode/
5 |
6 | #Project-specific folders
7 | *obj/
8 | *bin/
9 | *temp/
10 |
11 | #Nuke output folder
12 | /output/
13 |
14 | #Project-specific files
15 | */build.schema.json
16 |
17 | #User-specific files
18 | *.user
--------------------------------------------------------------------------------
/samples/MultiProjectApplication/Module1/Views/Module1View.xaml.cs:
--------------------------------------------------------------------------------
1 | using Module1.ViewModels;
2 |
3 | namespace Module1.Views;
4 |
5 | public sealed partial class Module1View
6 | {
7 | public Module1View(Module1ViewModel viewModel)
8 | {
9 | DataContext = viewModel;
10 | InitializeComponent();
11 | }
12 | }
--------------------------------------------------------------------------------
/samples/MultiProjectApplication/Module2/Views/Module2View.xaml.cs:
--------------------------------------------------------------------------------
1 | using Module2.ViewModels;
2 |
3 | namespace Module2.Views;
4 |
5 | public sealed partial class Module2View
6 | {
7 | public Module2View(Module2ViewModel viewModel)
8 | {
9 | DataContext = viewModel;
10 | InitializeComponent();
11 | }
12 | }
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/.gitignore:
--------------------------------------------------------------------------------
1 | #IDE folders
2 | *.idea/
3 | *.vs/
4 | *.vscode/
5 |
6 | #Project-specific folders
7 | *obj/
8 | *bin/
9 | *temp/
10 |
11 | #Deprecated Nuget folder
12 | /packages/
13 |
14 | #Nuke output folder
15 | /output/
16 |
17 | #Project-specific files
18 | */build.schema.json
19 |
20 | #User-specific files
21 | *.user
--------------------------------------------------------------------------------
/samples/SingleProjectDIApplication/RevitAddIn/Views/RevitAddInView.xaml.cs:
--------------------------------------------------------------------------------
1 | using RevitAddIn.ViewModels;
2 |
3 | namespace RevitAddIn.Views;
4 |
5 | public sealed partial class RevitAddInView
6 | {
7 | public RevitAddInView(RevitAddInViewModel viewModel)
8 | {
9 | DataContext = viewModel;
10 | InitializeComponent();
11 | }
12 | }
--------------------------------------------------------------------------------
/samples/SingleProjectHostingApplication/RevitAddIn/Views/RevitAddInView.xaml.cs:
--------------------------------------------------------------------------------
1 | using RevitAddIn.ViewModels;
2 |
3 | namespace RevitAddIn.Views;
4 |
5 | public sealed partial class RevitAddInView
6 | {
7 | public RevitAddInView(RevitAddInViewModel viewModel)
8 | {
9 | DataContext = viewModel;
10 | InitializeComponent();
11 | }
12 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Solution/.gitignore:
--------------------------------------------------------------------------------
1 | #IDE folders
2 | *.idea/
3 | *.vs/
4 | *.vscode/
5 |
6 | #Project-specific folders
7 | *obj/
8 | *bin/
9 | *temp/
10 |
11 | #Deprecated Nuget folder
12 | /packages/
13 |
14 | #Nuke output folder
15 | /output/
16 |
17 | #Project-specific files
18 | */build.schema.json
19 |
20 | #User-specific files
21 | *.user
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/source/ModalModule/Views/ModalModuleView.xaml.cs:
--------------------------------------------------------------------------------
1 | using ModalModule.ViewModels;
2 |
3 | namespace ModalModule.Views;
4 |
5 | public sealed partial class ModalModuleView
6 | {
7 | public ModalModuleView(ModalModuleViewModel viewModel)
8 | {
9 | DataContext = viewModel;
10 | InitializeComponent();
11 | }
12 | }
--------------------------------------------------------------------------------
/samples/SingleProjectWpfModalApplication/RevitAddIn/Views/RevitAddInView.xaml.cs:
--------------------------------------------------------------------------------
1 | using RevitAddIn.ViewModels;
2 |
3 | namespace RevitAddIn.Views;
4 |
5 | public sealed partial class RevitAddInView
6 | {
7 | public RevitAddInView(RevitAddInViewModel viewModel)
8 | {
9 | DataContext = viewModel;
10 | InitializeComponent();
11 | }
12 | }
--------------------------------------------------------------------------------
/samples/SingleProjectWpfModelessApplication/RevitAddIn/Views/RevitAddinView.xaml.cs:
--------------------------------------------------------------------------------
1 | using RevitAddIn.ViewModels;
2 |
3 | namespace RevitAddIn.Views;
4 |
5 | public sealed partial class RevitAddInView
6 | {
7 | public RevitAddInView(RevitAddInViewModel viewModel)
8 | {
9 | DataContext = viewModel;
10 | InitializeComponent();
11 | }
12 | }
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/source/ModelessModule/Views/ModelessModuleView.xaml.cs:
--------------------------------------------------------------------------------
1 | using ModelessModule.ViewModels;
2 |
3 | namespace ModelessModule.Views;
4 |
5 | public sealed partial class ModelessModuleView
6 | {
7 | public ModelessModuleView(ModelessModuleViewModel viewModel)
8 | {
9 | DataContext = viewModel;
10 | InitializeComponent();
11 | }
12 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn/Views/Nice3point.Revit.AddInView.xaml.cs:
--------------------------------------------------------------------------------
1 | using Nice3point.Revit.AddIn.ViewModels;
2 |
3 | namespace Nice3point.Revit.AddIn.Views;
4 |
5 | public sealed partial class Nice3point.Revit.AddInView
6 | {
7 | public Nice3point.Revit.AddInView(Nice3point.Revit.AddInViewModel viewModel)
8 | {
9 | DataContext = viewModel;
10 | InitializeComponent();
11 | }
12 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Module/Views/Nice3point.Revit.AddInView.xaml.cs:
--------------------------------------------------------------------------------
1 | using Nice3point.Revit.AddIn.ViewModels;
2 |
3 | namespace Nice3point.Revit.AddIn.Views;
4 |
5 | public sealed partial class Nice3point.Revit.AddInView
6 | {
7 | public Nice3point.Revit.AddInView(Nice3point.Revit.AddInViewModel viewModel)
8 | {
9 | DataContext = viewModel;
10 | InitializeComponent();
11 | }
12 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Application/Commands/StartupCommand.cs:
--------------------------------------------------------------------------------
1 | using Autodesk.Revit.Attributes;
2 | using Nice3point.Revit.Toolkit.External;
3 |
4 | namespace Nice3point.Revit.AddIn.Commands;
5 |
6 | ///
7 | /// External command entry point
8 | ///
9 | [UsedImplicitly]
10 | [Transaction(TransactionMode.Manual)]
11 | public class StartupCommand : ExternalCommand
12 | {
13 | public override void Execute()
14 | {
15 | }
16 | }
--------------------------------------------------------------------------------
/samples/MultiProjectApplication/RevitAddIn/RevitAddIn.addin:
--------------------------------------------------------------------------------
1 |
2 |
3 | RevitAddIn
4 | RevitAddIn/RevitAddIn.dll
5 | F131440A-728B-46F5-802E-E6F48C630FC4
6 | RevitAddIn.Application
7 | Development
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/samples/SingleProjectApplication/RevitAddIn/RevitAddIn.addin:
--------------------------------------------------------------------------------
1 |
2 |
3 | RevitAddIn
4 | RevitAddIn/RevitAddIn.dll
5 | 8F8F151B-8E8A-492A-B68C-736B9C385BFE
6 | RevitAddIn.Application
7 | Development
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/samples/SingleProjectDIApplication/RevitAddIn/RevitAddIn.addin:
--------------------------------------------------------------------------------
1 |
2 |
3 | RevitAddIn
4 | RevitAddIn/RevitAddIn.dll
5 | 64047F09-FAA8-474D-A962-04BBB82D2263
6 | RevitAddIn.Application
7 | Development
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/source/RevitAddIn/RevitAddIn.addin:
--------------------------------------------------------------------------------
1 |
2 |
3 | RevitAddIn
4 | RevitAddIn/RevitAddIn.dll
5 | 9D87DD1A-F364-4CA1-85BB-8E096231FBD5
6 | RevitAddIn.Application
7 | Development
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/samples/SingleProjectHostingApplication/RevitAddIn/RevitAddIn.addin:
--------------------------------------------------------------------------------
1 |
2 |
3 | RevitAddIn
4 | RevitAddIn/RevitAddIn.dll
5 | 448AA94D-A0D9-43E2-AD65-8939072953FF
6 | RevitAddIn.Application
7 | Development
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/samples/SingleProjectWpfModalApplication/RevitAddIn/RevitAddIn.addin:
--------------------------------------------------------------------------------
1 |
2 |
3 | RevitAddIn
4 | RevitAddIn/RevitAddIn.dll
5 | 1570D4AE-71AB-49DC-AEF8-18502D105804
6 | RevitAddIn.Application
7 | Development
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/samples/SingleProjectWpfModelessApplication/RevitAddIn/RevitAddin.addin:
--------------------------------------------------------------------------------
1 |
2 |
3 | RevitAddIn
4 | RevitAddIn/RevitAddIn.dll
5 | 8ED7D635-DF57-4782-8989-AB3F8B9EB8C2
6 | RevitAddIn.Application
7 | Development
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn/Config/Options/ApplicationOptions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using Microsoft.Extensions.Hosting;
3 |
4 | namespace Nice3point.Revit.AddIn.Config.Options;
5 |
6 | public static class ApplicationOptions
7 | {
8 | ///
9 | /// Add global Host configuration
10 | ///
11 | public static void AddApplicationOptions(this IServiceCollection services)
12 | {
13 | services.Configure(options => options.SuppressStatusMessages = true);
14 | }
15 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Application/Config/Options/ApplicationOptions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using Microsoft.Extensions.Hosting;
3 |
4 | namespace Nice3point.Revit.AddIn.Config.Options;
5 |
6 | public static class ApplicationOptions
7 | {
8 | ///
9 | /// Add global Host configuration
10 | ///
11 | public static void AddApplicationOptions(this IServiceCollection services)
12 | {
13 | services.Configure(options => options.SuppressStatusMessages = true);
14 | }
15 | }
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/source/RevitAddIn/Commands/ShowModalWindowCommand.cs:
--------------------------------------------------------------------------------
1 | using Autodesk.Revit.Attributes;
2 | using ModalModule.Views;
3 | using Nice3point.Revit.Toolkit.External;
4 |
5 | namespace RevitAddIn.Commands;
6 |
7 | ///
8 | /// External command entry point
9 | ///
10 | [UsedImplicitly]
11 | [Transaction(TransactionMode.Manual)]
12 | public class ShowModalWindowCommand : ExternalCommand
13 | {
14 | public override void Execute()
15 | {
16 | var view = Host.GetService();
17 | view.ShowDialog();
18 | }
19 | }
--------------------------------------------------------------------------------
/samples/SingleProjectDIApplication/RevitAddIn/Commands/StartupCommand.cs:
--------------------------------------------------------------------------------
1 | using Autodesk.Revit.Attributes;
2 | using Nice3point.Revit.Toolkit.External;
3 | using RevitAddIn.ViewModels;
4 | using RevitAddIn.Views;
5 |
6 | namespace RevitAddIn.Commands;
7 |
8 | ///
9 | /// External command entry point
10 | ///
11 | [UsedImplicitly]
12 | [Transaction(TransactionMode.Manual)]
13 | public class StartupCommand : ExternalCommand
14 | {
15 | public override void Execute()
16 | {
17 | var view = Host.GetService();
18 | view.ShowDialog();
19 | }
20 | }
--------------------------------------------------------------------------------
/samples/SingleProjectHostingApplication/RevitAddIn/Commands/StartupCommand.cs:
--------------------------------------------------------------------------------
1 | using Autodesk.Revit.Attributes;
2 | using Nice3point.Revit.Toolkit.External;
3 | using RevitAddIn.ViewModels;
4 | using RevitAddIn.Views;
5 |
6 | namespace RevitAddIn.Commands;
7 |
8 | ///
9 | /// External command entry point
10 | ///
11 | [UsedImplicitly]
12 | [Transaction(TransactionMode.Manual)]
13 | public class StartupCommand : ExternalCommand
14 | {
15 | public override void Execute()
16 | {
17 | var view = Host.GetService();
18 | view.ShowDialog();
19 | }
20 | }
--------------------------------------------------------------------------------
/samples/MultiProjectApplication/RevitAddIn/Commands/Module1StartupCommand.cs:
--------------------------------------------------------------------------------
1 | using Autodesk.Revit.Attributes;
2 | using Module1.ViewModels;
3 | using Module1.Views;
4 | using Nice3point.Revit.Toolkit.External;
5 |
6 | namespace RevitAddIn.Commands;
7 |
8 | ///
9 | /// External command entry point
10 | ///
11 | [UsedImplicitly]
12 | [Transaction(TransactionMode.Manual)]
13 | public class Module1StartupCommand : ExternalCommand
14 | {
15 | public override void Execute()
16 | {
17 | var viewModel = new Module1ViewModel();
18 | var view = new Module1View(viewModel);
19 | view.ShowDialog();
20 | }
21 | }
--------------------------------------------------------------------------------
/samples/MultiProjectApplication/RevitAddIn/Commands/Module2StartupCommand.cs:
--------------------------------------------------------------------------------
1 | using Autodesk.Revit.Attributes;
2 | using Module2.ViewModels;
3 | using Module2.Views;
4 | using Nice3point.Revit.Toolkit.External;
5 |
6 | namespace RevitAddIn.Commands;
7 |
8 | ///
9 | /// External command entry point
10 | ///
11 | [UsedImplicitly]
12 | [Transaction(TransactionMode.Manual)]
13 | public class Module2StartupCommand : ExternalCommand
14 | {
15 | public override void Execute()
16 | {
17 | var viewModel = new Module2ViewModel();
18 | var view = new Module2View(viewModel);
19 | view.ShowDialog();
20 | }
21 | }
--------------------------------------------------------------------------------
/samples/SingleProjectWpfModalApplication/RevitAddIn/Commands/StartupCommand.cs:
--------------------------------------------------------------------------------
1 | using Autodesk.Revit.Attributes;
2 | using Nice3point.Revit.Toolkit.External;
3 | using RevitAddIn.ViewModels;
4 | using RevitAddIn.Views;
5 |
6 | namespace RevitAddIn.Commands;
7 |
8 | ///
9 | /// External command entry point
10 | ///
11 | [UsedImplicitly]
12 | [Transaction(TransactionMode.Manual)]
13 | public class StartupCommand : ExternalCommand
14 | {
15 | public override void Execute()
16 | {
17 | var viewModel = new RevitAddInViewModel();
18 | var view = new RevitAddInView(viewModel);
19 | view.ShowDialog();
20 | }
21 | }
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/.github/workflows/Compile.yml:
--------------------------------------------------------------------------------
1 | name: Compile
2 |
3 | on:
4 | push:
5 | branches:
6 | - '*'
7 | pull_request:
8 |
9 | jobs:
10 | compile:
11 | name: Compile
12 | runs-on: windows-2022
13 | steps:
14 | - name: Checkout
15 | uses: actions/checkout@v4
16 | - name: Cache packages
17 | uses: actions/cache@v4
18 | with:
19 | path: |
20 | .nuke/temp
21 | ~/.nuget/packages
22 | key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
23 | - name: Compile solution
24 | run: ./.nuke/build.cmd
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/install/Installer.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | enable
5 | Exe
6 | latest
7 | x64
8 | net48
9 | false
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Solution/install/Installer.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | enable
5 | Exe
6 | latest
7 | x64
8 | net48
9 | false
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Solution/.github/workflows/Compile.yml:
--------------------------------------------------------------------------------
1 | name: Compile
2 |
3 | on:
4 | push:
5 | branches:
6 | - '*'
7 | pull_request:
8 |
9 | jobs:
10 | compile:
11 | name: Compile
12 | runs-on: windows-2022
13 | steps:
14 | - name: Checkout
15 | uses: actions/checkout@v4
16 |
17 | - name: Cache packages
18 | uses: actions/cache@v4
19 | with:
20 | path: |
21 | .nuke/temp
22 | ~/.nuget/packages
23 | key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
24 |
25 | - name: Compile solution
26 | run: ./.nuke/build.cmd
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/build/Build.Regex.cs:
--------------------------------------------------------------------------------
1 | using System.Text.RegularExpressions;
2 |
3 | sealed partial class Build
4 | {
5 | ///
6 | /// Regex for parsing the product version.
7 | ///
8 | readonly Regex YearRegex = YearRegexGenerator();
9 |
10 | ///
11 | /// Regex for parsing Process arguments from the output.
12 | ///
13 | readonly Regex ArgumentsRegex = ArgumentsRegexGenerator();
14 |
15 | [GeneratedRegex(@"\d{4}")]
16 | private static partial Regex YearRegexGenerator();
17 |
18 | [GeneratedRegex("'(.+?)'", RegexOptions.Compiled)]
19 | private static partial Regex ArgumentsRegexGenerator();
20 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn/ViewModels/Nice3point.Revit.AddInViewModel.cs:
--------------------------------------------------------------------------------
1 | #if (log && Container)
2 | using Serilog;
3 | #endif
4 | #if (log && Hosting)
5 | using Microsoft.Extensions.Logging;
6 | #endif
7 |
8 | namespace Nice3point.Revit.AddIn.ViewModels;
9 |
10 | #if (!log)
11 | public sealed class Nice3point.Revit.AddInViewModel : ObservableObject
12 | #elseif (Container)
13 | public sealed class Nice3point.Revit.AddInViewModel(ILogger logger) : ObservableObject
14 | #elseif (Hosting)
15 | public sealed class Nice3point.Revit.AddInViewModel(ILogger logger) : ObservableObject
16 | #else
17 | public sealed class Nice3point.Revit.AddInViewModel : ObservableObject
18 | #endif
19 | {
20 | }
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/source/RevitAddIn/Commands/ShowModelessWindowCommand.cs:
--------------------------------------------------------------------------------
1 | using Autodesk.Revit.Attributes;
2 | using ModelessModule.Services;
3 | using ModelessModule.Views;
4 | using Nice3point.Revit.Toolkit.External;
5 |
6 | namespace RevitAddIn.Commands;
7 |
8 | ///
9 | /// External command entry point
10 | ///
11 | [UsedImplicitly]
12 | [Transaction(TransactionMode.Manual)]
13 | public class ShowModelessWindowCommand : ExternalCommand
14 | {
15 | public override void Execute()
16 | {
17 | var modelessController = Host.GetService();
18 | var view = Host.GetService();
19 | modelessController.Show(view);
20 | }
21 | }
--------------------------------------------------------------------------------
/samples/MultiProjectApplication/Module1/ViewModels/Module1ViewModel.cs:
--------------------------------------------------------------------------------
1 | using Module3;
2 | using Module3.Enums;
3 |
4 | namespace Module1.ViewModels;
5 |
6 | public sealed partial class Module1ViewModel : ObservableObject
7 | {
8 | [ObservableProperty] private string _projectName;
9 |
10 | public Module1ViewModel()
11 | {
12 | ProjectName = new DatabaseConnection(EntryKey.Data).Load("ProjectName");
13 | }
14 |
15 | [RelayCommand]
16 | private void SaveProjectName()
17 | {
18 | var connection = new DatabaseConnection(EntryKey.Data);
19 | connection.BeginTransaction();
20 | connection.Save("ProjectName", ProjectName);
21 | connection.Close();
22 | }
23 | }
--------------------------------------------------------------------------------
/samples/MultiProjectApplication/Module2/ViewModels/Module2ViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace Module2.ViewModels;
2 |
3 | public sealed partial class Module2ViewModel : ObservableObject
4 | {
5 | [ObservableProperty] private string _projectName = Context.ActiveDocument?.ProjectInformation.Name;
6 |
7 | [RelayCommand]
8 | private void SaveProjectName()
9 | {
10 | var activeDocument = Context.ActiveDocument;
11 | if (activeDocument is null) return;
12 |
13 | var transaction = new Transaction(activeDocument);
14 | transaction.Start("Save project name");
15 |
16 | activeDocument.ProjectInformation.Name = ProjectName;
17 |
18 | transaction.Commit();
19 | }
20 | }
--------------------------------------------------------------------------------
/samples/SingleProjectDIApplication/RevitAddIn/ViewModels/RevitAddInViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace RevitAddIn.ViewModels;
2 |
3 | public sealed partial class RevitAddInViewModel : ObservableObject
4 | {
5 | [ObservableProperty] private string _projectName = Context.ActiveDocument?.ProjectInformation.Name;
6 |
7 | [RelayCommand]
8 | private void SaveProjectName()
9 | {
10 | var activeDocument = Context.ActiveDocument;
11 | if (activeDocument is null) return;
12 |
13 | var transaction = new Transaction(activeDocument);
14 | transaction.Start("Save project name");
15 |
16 | activeDocument.ProjectInformation.Name = ProjectName;
17 |
18 | transaction.Commit();
19 | }
20 | }
--------------------------------------------------------------------------------
/samples/SingleProjectHostingApplication/RevitAddIn/ViewModels/RevitAddInViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace RevitAddIn.ViewModels;
2 |
3 | public sealed partial class RevitAddInViewModel : ObservableObject
4 | {
5 | [ObservableProperty] private string _projectName = Context.ActiveDocument?.ProjectInformation.Name;
6 |
7 | [RelayCommand]
8 | private void SaveProjectName()
9 | {
10 | var activeDocument = Context.ActiveDocument;
11 | if (activeDocument is null) return;
12 |
13 | var transaction = new Transaction(activeDocument);
14 | transaction.Start("Save project name");
15 |
16 | activeDocument.ProjectInformation.Name = ProjectName;
17 |
18 | transaction.Commit();
19 | }
20 | }
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/build/.editorconfig:
--------------------------------------------------------------------------------
1 | # noinspection EditorConfigKeyCorrectness
2 | [*.cs]
3 | dotnet_style_qualification_for_field = false:warning
4 | dotnet_style_qualification_for_property = false:warning
5 | dotnet_style_qualification_for_method = false:warning
6 | dotnet_style_qualification_for_event = false:warning
7 | dotnet_style_require_accessibility_modifiers = never:warning
8 |
9 | csharp_style_expression_bodied_methods = true:silent
10 | csharp_style_expression_bodied_properties = true:warning
11 | csharp_style_expression_bodied_indexers = true:warning
12 | csharp_style_expression_bodied_accessors = true:warning
13 |
14 | resharper_check_namespace_highlighting = none
15 | resharper_class_never_instantiated_global_highlighting = none
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Solution/build/.editorconfig:
--------------------------------------------------------------------------------
1 | # noinspection EditorConfigKeyCorrectness
2 | [*.cs]
3 | dotnet_style_qualification_for_field = false:warning
4 | dotnet_style_qualification_for_property = false:warning
5 | dotnet_style_qualification_for_method = false:warning
6 | dotnet_style_qualification_for_event = false:warning
7 | dotnet_style_require_accessibility_modifiers = never:warning
8 |
9 | csharp_style_expression_bodied_methods = true:silent
10 | csharp_style_expression_bodied_properties = true:warning
11 | csharp_style_expression_bodied_indexers = true:warning
12 | csharp_style_expression_bodied_accessors = true:warning
13 |
14 | resharper_check_namespace_highlighting = none
15 | resharper_class_never_instantiated_global_highlighting = none
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/build/Build.Publish.Clean.cs:
--------------------------------------------------------------------------------
1 | using Nuke.Common.Tools.Git;
2 | using Nuke.Common.Utilities.Collections;
3 |
4 | sealed partial class Build
5 | {
6 | ///
7 | /// Revert the repository to the previous state after failed release.
8 | ///
9 | Target CleanFailedRelease => _ => _
10 | .Unlisted()
11 | .AssuredAfterFailure()
12 | .TriggeredBy(PublishGitHub)
13 | .OnlyWhenStatic(() => IsServerBuild)
14 | .OnlyWhenDynamic(() => !FailedTargets.IsEmpty())
15 | .Executes(() =>
16 | {
17 | Log.Information("Cleaning failed GitHub release");
18 | GitTasks.Git($"push --delete origin {ReleaseVersion}", logInvocation: false);
19 | });
20 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn/Views/Converters/InverseBooleanConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | using System.Windows.Data;
3 | using System.Windows.Markup;
4 |
5 | namespace Nice3point.Revit.AddIn.Views.Converters;
6 |
7 | public sealed class InverseBooleanConverter : MarkupExtension, IValueConverter
8 | {
9 | public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
10 | {
11 | return !(bool) value!;
12 | }
13 |
14 | public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
15 | {
16 | return !(bool) value!;
17 | }
18 |
19 | public override object ProvideValue(IServiceProvider serviceProvider)
20 | {
21 | return this;
22 | }
23 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Module/Views/Converters/InverseBooleanConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | using System.Windows.Data;
3 | using System.Windows.Markup;
4 |
5 | namespace Nice3point.Revit.AddIn.Views.Converters;
6 |
7 | public sealed class InverseBooleanConverter : MarkupExtension, IValueConverter
8 | {
9 | public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
10 | {
11 | return !(bool) value!;
12 | }
13 |
14 | public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
15 | {
16 | return !(bool) value!;
17 | }
18 |
19 | public override object ProvideValue(IServiceProvider serviceProvider)
20 | {
21 | return this;
22 | }
23 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Solution/build/Build.Publish.Clean.cs:
--------------------------------------------------------------------------------
1 | using Nuke.Common.Tools.Git;
2 | using Nuke.Common.Utilities.Collections;
3 |
4 | sealed partial class Build
5 | {
6 | ///
7 | /// Revert the repository to the previous state after failed release.
8 | ///
9 | Target CleanFailedRelease => _ => _
10 | .Unlisted()
11 | .AssuredAfterFailure()
12 | .TriggeredBy(PublishGitHub)
13 | .OnlyWhenStatic(() => IsServerBuild)
14 | .OnlyWhenDynamic(() => !FailedTargets.IsEmpty())
15 | .Executes(() =>
16 | {
17 | Log.Information("Cleaning failed GitHub release");
18 | GitTasks.Git($"push --delete origin {ReleaseVersion}", logInvocation: false);
19 | });
20 | }
--------------------------------------------------------------------------------
/samples/SingleProjectApplication/RevitAddIn/Application.cs:
--------------------------------------------------------------------------------
1 | using Nice3point.Revit.Toolkit.External;
2 | using RevitAddIn.Commands;
3 |
4 | namespace RevitAddIn;
5 |
6 | ///
7 | /// Application entry point
8 | ///
9 | [UsedImplicitly]
10 | public class Application : ExternalApplication
11 | {
12 | public override void OnStartup()
13 | {
14 | CreateRibbon();
15 | }
16 |
17 | private void CreateRibbon()
18 | {
19 | var panel = Application.CreatePanel("Commands", "RevitAddIn");
20 |
21 | panel.AddPushButton("Execute")
22 | .SetImage("/RevitAddIn;component/Resources/Icons/RibbonIcon16.png")
23 | .SetLargeImage("/RevitAddIn;component/Resources/Icons/RibbonIcon32.png");
24 | }
25 | }
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/build/Build.Compile.cs:
--------------------------------------------------------------------------------
1 | using Nuke.Common.Tools.DotNet;
2 | using static Nuke.Common.Tools.DotNet.DotNetTasks;
3 |
4 | sealed partial class Build
5 | {
6 | ///
7 | /// Compile all solution configurations.
8 | ///
9 | Target Compile => _ => _
10 | .DependsOn(Clean)
11 | .Executes(() =>
12 | {
13 | foreach (var configuration in GlobBuildConfigurations())
14 | {
15 | DotNetBuild(settings => settings
16 | .SetProjectFile(Solution)
17 | .SetConfiguration(configuration)
18 | .SetVersion(ReleaseVersionNumber)
19 | .SetVerbosity(DotNetVerbosity.minimal));
20 | }
21 | });
22 | }
--------------------------------------------------------------------------------
/samples/SingleProjectWpfModalApplication/RevitAddIn/Application.cs:
--------------------------------------------------------------------------------
1 | using Nice3point.Revit.Toolkit.External;
2 | using RevitAddIn.Commands;
3 |
4 | namespace RevitAddIn;
5 |
6 | ///
7 | /// Application entry point
8 | ///
9 | [UsedImplicitly]
10 | public class Application : ExternalApplication
11 | {
12 | public override void OnStartup()
13 | {
14 | CreateRibbon();
15 | }
16 |
17 | private void CreateRibbon()
18 | {
19 | var panel = Application.CreatePanel("Commands", "RevitAddIn");
20 |
21 | panel.AddPushButton("Execute")
22 | .SetImage("/RevitAddIn;component/Resources/Icons/RibbonIcon16.png")
23 | .SetLargeImage("/RevitAddIn;component/Resources/Icons/RibbonIcon32.png");
24 | }
25 | }
--------------------------------------------------------------------------------
/samples/SingleProjectWpfModelessApplication/RevitAddIn/Application.cs:
--------------------------------------------------------------------------------
1 | using Nice3point.Revit.Toolkit.External;
2 | using RevitAddIn.Commands;
3 |
4 | namespace RevitAddIn;
5 |
6 | ///
7 | /// Application entry point
8 | ///
9 | [UsedImplicitly]
10 | public class Application : ExternalApplication
11 | {
12 | public override void OnStartup()
13 | {
14 | CreateRibbon();
15 | }
16 |
17 | private void CreateRibbon()
18 | {
19 | var panel = Application.CreatePanel("Commands", "RevitAddIn");
20 |
21 | panel.AddPushButton("Execute")
22 | .SetImage("/RevitAddIn;component/Resources/Icons/RibbonIcon16.png")
23 | .SetLargeImage("/RevitAddIn;component/Resources/Icons/RibbonIcon32.png");
24 | }
25 | }
--------------------------------------------------------------------------------
/samples/SingleProjectDIApplication/RevitAddIn/Application.cs:
--------------------------------------------------------------------------------
1 | using Nice3point.Revit.Toolkit.External;
2 | using RevitAddIn.Commands;
3 |
4 | namespace RevitAddIn;
5 |
6 | ///
7 | /// Application entry point
8 | ///
9 | [UsedImplicitly]
10 | public class Application : ExternalApplication
11 | {
12 | public override void OnStartup()
13 | {
14 | Host.Start();
15 | CreateRibbon();
16 | }
17 |
18 | private void CreateRibbon()
19 | {
20 | var panel = Application.CreatePanel("Commands", "RevitAddIn");
21 |
22 | panel.AddPushButton("Execute")
23 | .SetImage("/RevitAddIn;component/Resources/Icons/RibbonIcon16.png")
24 | .SetLargeImage("/RevitAddIn;component/Resources/Icons/RibbonIcon32.png");
25 | }
26 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Solution/build/Build.Regex.cs:
--------------------------------------------------------------------------------
1 | using System.Text.RegularExpressions;
2 |
3 | sealed partial class Build
4 | {
5 | #if (bundle)
6 | ///
7 | /// Regex for parsing the product version.
8 | ///
9 | readonly Regex YearRegex = YearRegexGenerator();
10 | #endif
11 | #if (installer)
12 | ///
13 | /// Regex for parsing Process arguments from the output.
14 | ///
15 | readonly Regex ArgumentsRegex = ArgumentsRegexGenerator();
16 | #endif
17 | #if (bundle)
18 |
19 | [GeneratedRegex(@"\d{4}")]
20 | private static partial Regex YearRegexGenerator();
21 | #endif
22 | #if (installer)
23 |
24 | [GeneratedRegex("'(.+?)'", RegexOptions.Compiled)]
25 | private static partial Regex ArgumentsRegexGenerator();
26 | #endif
27 | }
--------------------------------------------------------------------------------
/samples/SingleProjectWpfModelessApplication/RevitAddIn/Commands/StartupCommand.cs:
--------------------------------------------------------------------------------
1 | using Autodesk.Revit.Attributes;
2 | using Nice3point.Revit.Toolkit.External;
3 | using RevitAddIn.ViewModels;
4 | using RevitAddIn.Views;
5 | using RevitAddIn.Utils;
6 |
7 | namespace RevitAddIn.Commands;
8 |
9 | ///
10 | /// External command entry point invoked from the Revit interface
11 | ///
12 | [UsedImplicitly]
13 | [Transaction(TransactionMode.Manual)]
14 | public class StartupCommand : ExternalCommand
15 | {
16 | public override void Execute()
17 | {
18 | if (WindowController.Focus()) return;
19 |
20 | var viewModel = new RevitAddInViewModel();
21 | var view = new RevitAddInView(viewModel);
22 | WindowController.Show(view, UiApplication.MainWindowHandle);
23 | }
24 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Solution/build/Build.Compile.cs:
--------------------------------------------------------------------------------
1 | using Nuke.Common.Tools.DotNet;
2 | using static Nuke.Common.Tools.DotNet.DotNetTasks;
3 |
4 | sealed partial class Build
5 | {
6 | ///
7 | /// Compile all solution configurations.
8 | ///
9 | Target Compile => _ => _
10 | .DependsOn(Clean)
11 | .Executes(() =>
12 | {
13 | foreach (var configuration in GlobBuildConfigurations())
14 | {
15 | DotNetBuild(settings => settings
16 | .SetProjectFile(Solution)
17 | .SetConfiguration(configuration)
18 | #if (HasArtifacts)
19 | .SetVersion(ReleaseVersionNumber)
20 | #endif
21 | .SetVerbosity(DotNetVerbosity.minimal));
22 | }
23 | });
24 | }
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/source/RevitAddIn/Config/SerializerConfiguration.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json;
2 | using System.Text.Json.Serialization;
3 | using Microsoft.Extensions.DependencyInjection;
4 |
5 | namespace RevitAddIn.Config;
6 |
7 | public static class SerializerConfiguration
8 | {
9 | ///
10 | /// Add JsonSerializerOptions, see example
11 | ///
12 | public static void AddSerializerOptions(this IServiceCollection services)
13 | {
14 | services.Configure(options =>
15 | {
16 | options.WriteIndented = true;
17 | options.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
18 | options.Converters.Add(new JsonStringEnumConverter());
19 | });
20 | }
21 | }
--------------------------------------------------------------------------------
/Contributing.md:
--------------------------------------------------------------------------------
1 | ## Fork, Clone, Branch and Create your PR
2 |
3 | 1. Fork the repo if you haven't already
4 | 2. Clone your fork locally
5 | 3. Create & push a feature branch
6 | 4. Create a [Draft Pull Request (PR)](https://github.blog/2019-02-14-introducing-draft-pull-requests/)
7 | 5. Work on your changes
8 |
9 | ## Rules
10 |
11 | - Follow the pattern of what you already see in the code.
12 | - When adding new classes/methods/changing existing code: check the functionality of the templates by creating a new project based on them.
13 |
14 | ## Naming of features and functionality
15 |
16 | The naming should be descriptive and direct, giving a clear idea of the functionality and usefulness in the future.
17 |
18 | ## Prerequisites for Compiling RevitTemplates
19 |
20 | 1. DotNet 8 SDK or newer
21 | 2. Visual Studio 2022 / JetBrains Rider 2023.3 or newer
--------------------------------------------------------------------------------
/samples/SingleProjectWpfModalApplication/RevitAddIn/ViewModels/RevitAddInViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace RevitAddIn.ViewModels;
2 |
3 | public sealed partial class RevitAddInViewModel : ObservableObject
4 | {
5 | [ObservableProperty] private string? _projectName = string.Empty;
6 |
7 | public RevitAddInViewModel()
8 | {
9 | ProjectName = Context.ActiveDocument?.ProjectInformation.Name;
10 | }
11 |
12 | [RelayCommand]
13 | private void SaveProjectName()
14 | {
15 | var activeDocument = Context.ActiveDocument;
16 | if (activeDocument is null) return;
17 |
18 | var transaction = new Transaction(activeDocument!);
19 | transaction.Start("Save project name");
20 |
21 | activeDocument.ProjectInformation.Name = ProjectName;
22 |
23 | transaction.Commit();
24 | }
25 | }
--------------------------------------------------------------------------------
/.github/workflows/Publish Release.yml:
--------------------------------------------------------------------------------
1 | name: Publish Release
2 |
3 | on:
4 | push:
5 | tags:
6 | - '*'
7 |
8 | jobs:
9 | windows:
10 | name: windows-2022
11 | runs-on: windows-2022
12 | steps:
13 | - name: Checkout
14 | uses: actions/checkout@v4
15 | with:
16 | fetch-depth: 0
17 | - name: Cache packages
18 | uses: actions/cache@v4
19 | with:
20 | path: |
21 | .nuke/temp
22 | ~/.nuget/packages
23 | key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj') }}
24 | - name: Run Nuke Build
25 | run: ./.nuke/build.cmd PublishGitHub PublishNuget
26 | env:
27 | NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
28 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
29 | PUBLISH_VERSION: ${{ github.ref_name }}
--------------------------------------------------------------------------------
/.run/Nuke.run.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
8 |
10 |
12 |
14 |
16 |
18 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.run/Nuke Plan.run.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
8 |
10 |
12 |
14 |
16 |
18 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/.run/Nuke.run.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
8 |
10 |
12 |
14 |
16 |
18 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Solution/.run/Nuke.run.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
8 |
10 |
12 |
14 |
16 |
18 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/.run/Nuke Plan.run.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
8 |
10 |
12 |
14 |
16 |
18 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn/Views/Converters/BooleanHiddenVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | using System.Windows.Data;
3 | using System.Windows.Markup;
4 | using Visibility = System.Windows.Visibility;
5 |
6 | namespace Nice3point.Revit.AddIn.Views.Converters;
7 |
8 | public sealed class BooleanHiddenVisibilityConverter : MarkupExtension, IValueConverter
9 | {
10 | public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
11 | {
12 | return (bool) value! ? Visibility.Visible : Visibility.Hidden;
13 | }
14 |
15 | public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
16 | {
17 | return (Visibility) value! == Visibility.Visible;
18 | }
19 |
20 | public override object ProvideValue(IServiceProvider serviceProvider)
21 | {
22 | return this;
23 | }
24 | }
--------------------------------------------------------------------------------
/samples/SingleProjectHostingApplication/RevitAddIn/Application.cs:
--------------------------------------------------------------------------------
1 | using Nice3point.Revit.Toolkit.External;
2 | using RevitAddIn.Commands;
3 |
4 | namespace RevitAddIn;
5 |
6 | ///
7 | /// Application entry point
8 | ///
9 | [UsedImplicitly]
10 | public class Application : ExternalApplication
11 | {
12 | public override void OnStartup()
13 | {
14 | Host.Start();
15 | CreateRibbon();
16 | }
17 |
18 | public override void OnShutdown()
19 | {
20 | Host.Stop();
21 | }
22 |
23 | private void CreateRibbon()
24 | {
25 | var panel = Application.CreatePanel("Commands", "RevitAddIn");
26 |
27 | panel.AddPushButton("Execute")
28 | .SetImage("/RevitAddIn;component/Resources/Icons/RibbonIcon16.png")
29 | .SetLargeImage("/RevitAddIn;component/Resources/Icons/RibbonIcon32.png");
30 | }
31 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Module/Views/Converters/BooleanHiddenVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | using System.Windows.Data;
3 | using System.Windows.Markup;
4 | using Visibility = System.Windows.Visibility;
5 |
6 | namespace Nice3point.Revit.AddIn.Views.Converters;
7 |
8 | public sealed class BooleanHiddenVisibilityConverter : MarkupExtension, IValueConverter
9 | {
10 | public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
11 | {
12 | return (bool) value! ? Visibility.Visible : Visibility.Hidden;
13 | }
14 |
15 | public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
16 | {
17 | return (Visibility) value! == Visibility.Visible;
18 | }
19 |
20 | public override object ProvideValue(IServiceProvider serviceProvider)
21 | {
22 | return this;
23 | }
24 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn/Views/Converters/BooleanCollapsedVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | using System.Windows.Data;
3 | using System.Windows.Markup;
4 | using Visibility = System.Windows.Visibility;
5 |
6 | namespace Nice3point.Revit.AddIn.Views.Converters;
7 |
8 | public sealed class BooleanCollapsedVisibilityConverter : MarkupExtension, IValueConverter
9 | {
10 | public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
11 | {
12 | return (bool) value! ? Visibility.Visible : Visibility.Collapsed;
13 | }
14 |
15 | public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
16 | {
17 | return (Visibility) value! == Visibility.Visible;
18 | }
19 |
20 | public override object ProvideValue(IServiceProvider serviceProvider)
21 | {
22 | return this;
23 | }
24 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Solution/.run/Nuke Plan.run.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
8 |
10 |
12 |
14 |
16 |
18 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Module/Views/Converters/BooleanCollapsedVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | using System.Windows.Data;
3 | using System.Windows.Markup;
4 | using Visibility = System.Windows.Visibility;
5 |
6 | namespace Nice3point.Revit.AddIn.Views.Converters;
7 |
8 | public sealed class BooleanCollapsedVisibilityConverter : MarkupExtension, IValueConverter
9 | {
10 | public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
11 | {
12 | return (bool) value! ? Visibility.Visible : Visibility.Collapsed;
13 | }
14 |
15 | public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
16 | {
17 | return (Visibility) value! == Visibility.Visible;
18 | }
19 |
20 | public override object ProvideValue(IServiceProvider serviceProvider)
21 | {
22 | return this;
23 | }
24 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn/Views/Converters/InverseBooleanHiddenVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | using System.Windows.Data;
3 | using System.Windows.Markup;
4 | using Visibility = System.Windows.Visibility;
5 |
6 | namespace Nice3point.Revit.AddIn.Views.Converters;
7 |
8 | public class InverseBooleanHiddenVisibilityConverter : MarkupExtension, IValueConverter
9 | {
10 | public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
11 | {
12 | return (bool) value! == false ? Visibility.Visible : Visibility.Hidden;
13 | }
14 |
15 | public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
16 | {
17 | return (Visibility) value! != Visibility.Visible;
18 | }
19 |
20 | public override object ProvideValue(IServiceProvider serviceProvider)
21 | {
22 | return this;
23 | }
24 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Module/Views/Converters/InverseBooleanHiddenVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | using System.Windows.Data;
3 | using System.Windows.Markup;
4 | using Visibility = System.Windows.Visibility;
5 |
6 | namespace Nice3point.Revit.AddIn.Views.Converters;
7 |
8 | public class InverseBooleanHiddenVisibilityConverter : MarkupExtension, IValueConverter
9 | {
10 | public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
11 | {
12 | return (bool) value! == false ? Visibility.Visible : Visibility.Hidden;
13 | }
14 |
15 | public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
16 | {
17 | return (Visibility) value! != Visibility.Visible;
18 | }
19 |
20 | public override object ProvideValue(IServiceProvider serviceProvider)
21 | {
22 | return this;
23 | }
24 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn/Views/Converters/InverseBooleanCollapsedVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | using System.Windows.Data;
3 | using System.Windows.Markup;
4 | using Visibility = System.Windows.Visibility;
5 |
6 | namespace Nice3point.Revit.AddIn.Views.Converters;
7 |
8 | public sealed class InverseBooleanCollapsedVisibilityConverter : MarkupExtension, IValueConverter
9 | {
10 | public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
11 | {
12 | return (bool) value! == false ? Visibility.Visible : Visibility.Collapsed;
13 | }
14 |
15 | public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
16 | {
17 | return (Visibility) value! != Visibility.Visible;
18 | }
19 |
20 | public override object ProvideValue(IServiceProvider serviceProvider)
21 | {
22 | return this;
23 | }
24 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Module/Views/Converters/InverseBooleanCollapsedVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | using System.Windows.Data;
3 | using System.Windows.Markup;
4 | using Visibility = System.Windows.Visibility;
5 |
6 | namespace Nice3point.Revit.AddIn.Views.Converters;
7 |
8 | public sealed class InverseBooleanCollapsedVisibilityConverter : MarkupExtension, IValueConverter
9 | {
10 | public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
11 | {
12 | return (bool) value! == false ? Visibility.Visible : Visibility.Collapsed;
13 | }
14 |
15 | public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
16 | {
17 | return (Visibility) value! != Visibility.Visible;
18 | }
19 |
20 | public override object ProvideValue(IServiceProvider serviceProvider)
21 | {
22 | return this;
23 | }
24 | }
--------------------------------------------------------------------------------
/samples/SingleProjectApplication/RevitAddIn/Commands/StartupCommand.cs:
--------------------------------------------------------------------------------
1 | using Autodesk.Revit.Attributes;
2 | using Nice3point.Revit.Toolkit.External;
3 | using Autodesk.Revit.UI;
4 | using Autodesk.Revit.UI.Selection;
5 | using Nice3point.Revit.Toolkit.Options;
6 |
7 | namespace RevitAddIn.Commands;
8 |
9 | ///
10 | /// External command entry point
11 | ///
12 | [UsedImplicitly]
13 | [Transaction(TransactionMode.Manual)]
14 | public class StartupCommand : ExternalCommand
15 | {
16 | public override void Execute()
17 | {
18 | var selectionConfiguration = new SelectionConfiguration()
19 | .Allow.Element(element => element is Wall);
20 |
21 | var reference = UiDocument.Selection.PickObject(ObjectType.Element, selectionConfiguration.Filter);
22 | var element = reference.ElementId.ToElement(Document)!;
23 |
24 | TaskDialog.Show("Selected element",element.Name);
25 | }
26 | }
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/build/Build.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | disable
6 | CS0649;CS0169
7 | latest
8 | true
9 | net9.0
10 | ..
11 | ..
12 | 1
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn/Views/Converters/EmptyCollectionVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Globalization;
3 | using System.Windows.Data;
4 | using System.Windows.Markup;
5 | using Visibility = System.Windows.Visibility;
6 |
7 | namespace Nice3point.Revit.AddIn.Views.Converters;
8 |
9 | public sealed class EmptyCollectionVisibilityConverter : MarkupExtension, IValueConverter
10 | {
11 | public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
12 | {
13 | var collection = (ICollection) value!;
14 | return collection.Count == 0 ? Visibility.Visible : Visibility.Collapsed;
15 | }
16 |
17 | public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
18 | {
19 | throw new NotSupportedException();
20 | }
21 |
22 | public override object ProvideValue(IServiceProvider serviceProvider)
23 | {
24 | return this;
25 | }
26 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Module/Views/Converters/EmptyCollectionVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Globalization;
3 | using System.Windows.Data;
4 | using System.Windows.Markup;
5 | using Visibility = System.Windows.Visibility;
6 |
7 | namespace Nice3point.Revit.AddIn.Views.Converters;
8 |
9 | public sealed class EmptyCollectionVisibilityConverter : MarkupExtension, IValueConverter
10 | {
11 | public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
12 | {
13 | var collection = (ICollection) value!;
14 | return collection.Count == 0 ? Visibility.Visible : Visibility.Collapsed;
15 | }
16 |
17 | public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
18 | {
19 | throw new NotSupportedException();
20 | }
21 |
22 | public override object ProvideValue(IServiceProvider serviceProvider)
23 | {
24 | return this;
25 | }
26 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn/Nice3point.Revit.AddIn.addin:
--------------------------------------------------------------------------------
1 |
2 | #if (Command)
3 |
4 | #elseif (Application)
5 |
6 | #endif
7 | Nice3point.Revit.AddIn
8 | Nice3point.Revit.AddIn\Nice3point.Revit.AddIn.dll
9 | AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA
10 | #if (Command)
11 | Nice3point.Revit.AddIn.Commands.StartupCommand
12 | Nice3point.Revit.AddIn
13 | #elseif (Application)
14 | Nice3point.Revit.AddIn.Application
15 | #endif
16 | Development
17 |
18 |
19 |
20 |
21 | False
22 | Nice3point.Revit.AddIn
23 |
24 |
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn/Views/Converters/InverseEmptyCollectionVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Globalization;
3 | using System.Windows.Data;
4 | using System.Windows.Markup;
5 | using Visibility = System.Windows.Visibility;
6 |
7 | namespace Nice3point.Revit.AddIn.Views.Converters;
8 |
9 | public sealed class InverseEmptyCollectionVisibilityConverter : MarkupExtension, IValueConverter
10 | {
11 | public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
12 | {
13 | var collection = (ICollection) value!;
14 | return collection.Count == 0 ? Visibility.Collapsed : Visibility.Visible;
15 | }
16 |
17 | public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
18 | {
19 | throw new NotSupportedException();
20 | }
21 |
22 | public override object ProvideValue(IServiceProvider serviceProvider)
23 | {
24 | return this;
25 | }
26 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn/Views/Nice3point.Revit.AddInView.xaml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
21 |
22 |
--------------------------------------------------------------------------------
/.run/Nuke Clean.run.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
8 |
10 |
12 |
14 |
16 |
18 |
20 |
21 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/samples/MultiProjectApplication/Module3/Schemas/ProjectInfoSchema.cs:
--------------------------------------------------------------------------------
1 | using Autodesk.Revit.DB.ExtensibleStorage;
2 |
3 | namespace Module3.Schemas;
4 |
5 | public static class ProjectInfoSchema
6 | {
7 | public static Schema Create()
8 | {
9 | var guid = new Guid("0E73AF93-E7F3-42E6-9BA5-AFC1CA23D42B");
10 | var schema = Schema.Lookup(guid);
11 | if (schema is not null) return schema;
12 |
13 | var builder = new SchemaBuilder(guid)
14 | .SetSchemaName("RevitAddInDatabase")
15 | .SetDocumentation("RevitAddIn data storage")
16 | .SetVendorId("RevitAddIn")
17 | .SetReadAccessLevel(AccessLevel.Public)
18 | .SetWriteAccessLevel(AccessLevel.Public);
19 |
20 | builder.AddSimpleField("ProjectNumber", typeof(string));
21 | builder.AddSimpleField("ProjectName", typeof(string));
22 | builder.AddSimpleField("ProjectAddress", typeof(string));
23 |
24 | return builder.Finish();
25 | }
26 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Module/Views/Converters/InverseEmptyCollectionVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Globalization;
3 | using System.Windows.Data;
4 | using System.Windows.Markup;
5 | using Visibility = System.Windows.Visibility;
6 |
7 | namespace Nice3point.Revit.AddIn.Views.Converters;
8 |
9 | public sealed class InverseEmptyCollectionVisibilityConverter : MarkupExtension, IValueConverter
10 | {
11 | public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
12 | {
13 | var collection = (ICollection) value!;
14 | return collection.Count == 0 ? Visibility.Collapsed : Visibility.Visible;
15 | }
16 |
17 | public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
18 | {
19 | throw new NotSupportedException();
20 | }
21 |
22 | public override object ProvideValue(IServiceProvider serviceProvider)
23 | {
24 | return this;
25 | }
26 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Module/Views/Nice3point.Revit.AddInView.xaml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
21 |
22 |
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Application/Nice3point.Revit.AddIn.addin:
--------------------------------------------------------------------------------
1 |
2 | #if (Command)
3 |
4 | #elseif (Application)
5 |
6 | #endif
7 | Nice3point.Revit.AddIn
8 | Nice3point.Revit.AddIn\Nice3point.Revit.AddIn.dll
9 | AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA
10 | #if (Command)
11 | Nice3point.Revit.AddIn.Commands.StartupCommand
12 | Nice3point.Revit.AddIn
13 | #elseif (Application)
14 | Nice3point.Revit.AddIn.Application
15 | #endif
16 | Development
17 |
18 |
19 |
20 |
21 | False
22 | Nice3point.Revit.AddIn
23 |
24 |
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Solution/build/Build.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | disable
6 | CS0649;CS0169
7 | latest
8 | true
9 | net9.0
10 | ..
11 | ..
12 | 1
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/build/Build.cs:
--------------------------------------------------------------------------------
1 | using System.IO.Enumeration;
2 | using JetBrains.Annotations;
3 |
4 | [PublicAPI]
5 | sealed partial class Build : NukeBuild
6 | {
7 | ///
8 | /// Pipeline entry point.
9 | ///
10 | public static int Main() => Execute(build => build.Compile);
11 |
12 | ///
13 | /// Extract solution configuration names from the solution file.
14 | ///
15 | List GlobBuildConfigurations()
16 | {
17 | var configurations = Solution.Configurations
18 | .Select(pair => pair.Key)
19 | .Select(config => config.Remove(config.LastIndexOf('|')))
20 | .Where(config => Configurations.Any(wildcard => FileSystemName.MatchesSimpleExpression(wildcard, config)))
21 | .ToList();
22 |
23 | Assert.NotEmpty(configurations, $"No solution configurations have been found. Pattern: {string.Join(" | ", Configurations)}");
24 | return configurations;
25 | }
26 | }
--------------------------------------------------------------------------------
/samples/MultiProjectApplication/RevitAddIn/Application.cs:
--------------------------------------------------------------------------------
1 | using Nice3point.Revit.Toolkit.External;
2 | using RevitAddIn.Commands;
3 |
4 | namespace RevitAddIn;
5 |
6 | ///
7 | /// Application entry point
8 | ///
9 | [UsedImplicitly]
10 | public class Application : ExternalApplication
11 | {
12 | public override void OnStartup()
13 | {
14 | CreateRibbon();
15 | }
16 |
17 | private void CreateRibbon()
18 | {
19 | var panel = Application.CreatePanel("Commands", "RevitAddIn");
20 |
21 | panel.AddPushButton("Execute")
22 | .SetImage("/RevitAddIn;component/Resources/Icons/RibbonIcon16.png")
23 | .SetLargeImage("/RevitAddIn;component/Resources/Icons/RibbonIcon32.png");
24 |
25 | panel.AddPushButton("Execute")
26 | .SetImage("/RevitAddIn;component/Resources/Icons/RibbonIcon16.png")
27 | .SetLargeImage("/RevitAddIn;component/Resources/Icons/RibbonIcon32.png");
28 | }
29 | }
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/.run/Nuke Clean.run.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
8 |
10 |
12 |
14 |
16 |
18 |
20 |
21 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Solution/build/Build.cs:
--------------------------------------------------------------------------------
1 | using System.IO.Enumeration;
2 | using JetBrains.Annotations;
3 |
4 | [PublicAPI]
5 | sealed partial class Build : NukeBuild
6 | {
7 | ///
8 | /// Pipeline entry point.
9 | ///
10 | public static int Main() => Execute(build => build.Compile);
11 |
12 | ///
13 | /// Extract solution configuration names from the solution file.
14 | ///
15 | List GlobBuildConfigurations()
16 | {
17 | var configurations = Solution.Configurations
18 | .Select(pair => pair.Key)
19 | .Select(config => config.Remove(config.LastIndexOf('|')))
20 | .Where(config => Configurations.Any(wildcard => FileSystemName.MatchesSimpleExpression(wildcard, config)))
21 | .ToList();
22 |
23 | Assert.NotEmpty(configurations, $"No solution configurations have been found. Pattern: {string.Join(" | ", Configurations)}");
24 | return configurations;
25 | }
26 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Solution/.run/Nuke Clean.run.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
8 |
10 |
12 |
14 |
16 |
18 |
20 |
21 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/source/ModalModule/ViewModels/ModalModuleViewModel.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json;
2 | using Microsoft.Extensions.Logging;
3 | using Microsoft.Extensions.Options;
4 |
5 | namespace ModalModule.ViewModels;
6 |
7 | public sealed partial class ModalModuleViewModel(ILogger logger, IOptions serializerOptions) : ObservableObject
8 | {
9 | [ObservableProperty] private string _projectName = Context.ActiveDocument?.ProjectInformation.Name;
10 |
11 | [RelayCommand]
12 | private void SaveProjectName()
13 | {
14 | var activeDocument = Context.ActiveDocument;
15 | if (activeDocument is null) return;
16 |
17 | using var transaction = new Transaction(activeDocument);
18 | transaction.Start("Save project name");
19 |
20 | activeDocument.ProjectInformation.Name = ProjectName;
21 |
22 | transaction.Commit();
23 | logger.LogInformation("Saving successful");
24 | logger.LogInformation("{Info}", JsonSerializer.Serialize(this, serializerOptions.Value));
25 | }
26 | }
--------------------------------------------------------------------------------
/License.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Nice3point
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining
6 | a copy of this software and associated documentation files (the
7 | "Software"), to deal in the Software without restriction, including
8 | without limitation the rights to use, copy, modify, merge, publish,
9 | distribute, sublicense, and/or sell copies of the Software, and to
10 | permit persons to whom the Software is furnished to do so, subject to
11 | the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be
14 | included in all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn/Views/Converters/EmptyCollectionsVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Globalization;
3 | using System.Windows.Data;
4 | using System.Windows.Markup;
5 | using Visibility = System.Windows.Visibility;
6 |
7 | namespace Nice3point.Revit.AddIn.Views.Converters;
8 |
9 | public sealed class EmptyCollectionsVisibilityConverter : MarkupExtension, IMultiValueConverter
10 | {
11 | public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
12 | {
13 | foreach (var value in values)
14 | {
15 | switch (value)
16 | {
17 | case ICollection {Count: > 0}:
18 | case > 0:
19 | return Visibility.Collapsed;
20 | }
21 | }
22 |
23 | return Visibility.Visible;
24 | }
25 |
26 | public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
27 | {
28 | throw new NotSupportedException();
29 | }
30 |
31 | public override object ProvideValue(IServiceProvider serviceProvider)
32 | {
33 | return this;
34 | }
35 | }
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/source/RevitAddIn/Application.cs:
--------------------------------------------------------------------------------
1 | using Nice3point.Revit.Toolkit.External;
2 | using RevitAddIn.Commands;
3 |
4 | namespace RevitAddIn;
5 |
6 | ///
7 | /// Application entry point
8 | ///
9 | [UsedImplicitly]
10 | public class Application : ExternalApplication
11 | {
12 | public override void OnStartup()
13 | {
14 | Host.Start();
15 | CreateRibbon();
16 | }
17 |
18 | public override void OnShutdown()
19 | {
20 | Host.Stop();
21 | }
22 |
23 | private void CreateRibbon()
24 | {
25 | var panel = Application.CreatePanel("Commands", "RevitAddIn");
26 |
27 | panel.AddPushButton("Show\nModal window")
28 | .SetImage("/RevitAddIn;component/Resources/Icons/RibbonIcon16.png")
29 | .SetLargeImage("/RevitAddIn;component/Resources/Icons/RibbonIcon32.png");
30 |
31 | panel.AddPushButton("Show\nModeless window")
32 | .SetImage("/RevitAddIn;component/Resources/Icons/RibbonIcon16.png")
33 | .SetLargeImage("/RevitAddIn;component/Resources/Icons/RibbonIcon32.png");
34 | }
35 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Module/Views/Converters/EmptyCollectionsVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Globalization;
3 | using System.Windows.Data;
4 | using System.Windows.Markup;
5 | using Visibility = System.Windows.Visibility;
6 |
7 | namespace Nice3point.Revit.AddIn.Views.Converters;
8 |
9 | public sealed class EmptyCollectionsVisibilityConverter : MarkupExtension, IMultiValueConverter
10 | {
11 | public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
12 | {
13 | foreach (var value in values)
14 | {
15 | switch (value)
16 | {
17 | case ICollection {Count: > 0}:
18 | case > 0:
19 | return Visibility.Collapsed;
20 | }
21 | }
22 |
23 | return Visibility.Visible;
24 | }
25 |
26 | public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
27 | {
28 | throw new NotSupportedException();
29 | }
30 |
31 | public override object ProvideValue(IServiceProvider serviceProvider)
32 | {
33 | return this;
34 | }
35 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn/Views/Converters/InverseEmptyCollectionsVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Globalization;
3 | using System.Windows.Data;
4 | using System.Windows.Markup;
5 | using Visibility = System.Windows.Visibility;
6 |
7 | namespace Nice3point.Revit.AddIn.Views.Converters;
8 |
9 | public sealed class InverseEmptyCollectionsVisibilityConverter : MarkupExtension, IMultiValueConverter
10 | {
11 | public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
12 | {
13 | foreach (var value in values)
14 | {
15 | switch (value)
16 | {
17 | case ICollection {Count: > 0}:
18 | case > 0:
19 | return Visibility.Visible;
20 | }
21 | }
22 |
23 | return Visibility.Collapsed;
24 | }
25 |
26 | public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
27 | {
28 | throw new NotSupportedException();
29 | }
30 |
31 | public override object ProvideValue(IServiceProvider serviceProvider)
32 | {
33 | return this;
34 | }
35 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Module/Views/Converters/InverseEmptyCollectionsVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Globalization;
3 | using System.Windows.Data;
4 | using System.Windows.Markup;
5 | using Visibility = System.Windows.Visibility;
6 |
7 | namespace Nice3point.Revit.AddIn.Views.Converters;
8 |
9 | public sealed class InverseEmptyCollectionsVisibilityConverter : MarkupExtension, IMultiValueConverter
10 | {
11 | public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
12 | {
13 | foreach (var value in values)
14 | {
15 | switch (value)
16 | {
17 | case ICollection {Count: > 0}:
18 | case > 0:
19 | return Visibility.Visible;
20 | }
21 | }
22 |
23 | return Visibility.Collapsed;
24 | }
25 |
26 | public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
27 | {
28 | throw new NotSupportedException();
29 | }
30 |
31 | public override object ProvideValue(IServiceProvider serviceProvider)
32 | {
33 | return this;
34 | }
35 | }
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/.github/workflows/PublishRelease.yml:
--------------------------------------------------------------------------------
1 | name: Publish Release
2 |
3 | on:
4 | push:
5 | tags:
6 | - '*'
7 | workflow_dispatch:
8 | inputs:
9 | version:
10 | description: "Release version"
11 | required: true
12 | type: string
13 |
14 | jobs:
15 | release:
16 | name: Publish release
17 | runs-on: windows-2022
18 | steps:
19 | - name: Checkout
20 | uses: actions/checkout@v4
21 | with:
22 | fetch-depth: 0
23 |
24 | - name: Create release tag
25 | if: github.event_name == 'workflow_dispatch'
26 | shell: bash
27 | run: |
28 | set -e
29 | git tag ${{ github.event.inputs.version }}
30 | git push origin ${{ github.event.inputs.version }}
31 |
32 | - name: Cache packages
33 | uses: actions/cache@v4
34 | with:
35 | path: ~/.nuget/packages
36 | key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
37 |
38 | - name: Publish release
39 | run: ./.nuke/build.cmd PublishGitHub --ReleaseVersion ${{ github.event.inputs.version || github.ref_name }}
40 | env:
41 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Module/.template.config/template.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json.schemastore.org/template",
3 | "author": "Nice3point",
4 | "name": "Revit AddIn Module",
5 | "shortName": "revit-addin-module",
6 | "identity": "Nice3point.Revit.AddIn.Module",
7 | "defaultName": "RevitAddIn",
8 | "sourceName": "Nice3point.Revit.AddIn",
9 | "description": "Template for creating an empty module for multi-project Revit add-in",
10 | "classifications": [
11 | "Revit",
12 | "AddIn",
13 | "Library",
14 | "Module"
15 | ],
16 | "tags": {
17 | "type": "project",
18 | "language": "C#",
19 | "platform": ".NET"
20 | },
21 | "preferNameDirectory": true,
22 | "placeholderFilename": "keep.folder",
23 | "symbols": {
24 | "ui": {
25 | "type": "parameter",
26 | "displayName": "User interface",
27 | "dataType": "bool",
28 | "description": "Use WPF in the add-in",
29 | "defaultValue": "true"
30 | }
31 | },
32 | "sources": [
33 | {
34 | "modifiers": [
35 | {
36 | "condition": "!ui",
37 | "exclude": [
38 | "Models/**",
39 | "Views/**",
40 | "ViewModels/**"
41 | ]
42 | }
43 | ]
44 | }
45 | ]
46 | }
--------------------------------------------------------------------------------
/samples/SingleProjectDIApplication/RevitAddIn/Host.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using RevitAddIn.Views;
3 | using RevitAddIn.ViewModels;
4 |
5 | namespace RevitAddIn;
6 |
7 | ///
8 | /// Provides a host for the application's services and manages their lifetimes.
9 | ///
10 | public static class Host
11 | {
12 | private static IServiceProvider _serviceProvider;
13 |
14 | ///
15 | /// Starts the host and configures the application's services.
16 | ///
17 | public static void Start()
18 | {
19 | var services = new ServiceCollection();
20 |
21 | services.AddTransient();
22 | services.AddTransient();
23 |
24 | _serviceProvider = services.BuildServiceProvider();
25 | }
26 |
27 | ///
28 | /// Get service of type
29 | ///
30 | /// The type of service object to get
31 | /// There is no service of type
32 | public static T GetService() where T : class
33 | {
34 | return _serviceProvider.GetRequiredService();
35 | }
36 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Solution/.github/workflows/PublishRelease.yml:
--------------------------------------------------------------------------------
1 | name: Publish Release
2 |
3 | on:
4 | push:
5 | tags:
6 | - '*'
7 | workflow_dispatch:
8 | inputs:
9 | version:
10 | description: "Release version"
11 | required: true
12 | type: string
13 |
14 | jobs:
15 | release:
16 | name: Publish release
17 | runs-on: windows-2022
18 | steps:
19 | - name: Checkout
20 | uses: actions/checkout@v4
21 | with:
22 | fetch-depth: 0
23 |
24 | - name: Create release tag
25 | if: github.event_name == 'workflow_dispatch'
26 | shell: bash
27 | run: |
28 | set -e
29 | git tag ${{ github.event.inputs.version }}
30 | git push origin ${{ github.event.inputs.version }}
31 |
32 | - name: Cache packages
33 | uses: actions/cache@v4
34 | with:
35 | path: ~/.nuget/packages
36 | key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
37 |
38 | - name: Publish release
39 | run: ./.nuke/build.cmd PublishGitHub --ReleaseVersion ${{ github.event.inputs.version || github.ref_name }}
40 | env:
41 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn/Views/Converters/EnumHiddenVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | using System.Windows.Data;
3 | using System.Windows.Markup;
4 | using Visibility = System.Windows.Visibility;
5 |
6 | namespace Nice3point.Revit.AddIn.Views.Converters;
7 |
8 | public class EnumVisibilityConverter : MarkupExtension, IValueConverter where TEnum : Enum
9 | {
10 | public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
11 | {
12 | if (value is not TEnum valueEnum)
13 | {
14 | throw new ArgumentException($"{nameof(value)} is not type: {typeof(TEnum)}");
15 | }
16 |
17 | if (parameter is not TEnum parameterEnum)
18 | {
19 | throw new ArgumentException($"{nameof(parameter)} is not type: {typeof(TEnum)}");
20 | }
21 |
22 | return EqualityComparer.Default.Equals(valueEnum, parameterEnum) ? Visibility.Visible : Visibility.Hidden;
23 | }
24 |
25 | public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
26 | {
27 | throw new NotSupportedException();
28 | }
29 |
30 | public override object ProvideValue(IServiceProvider serviceProvider)
31 | {
32 | return this;
33 | }
34 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Module/Views/Converters/EnumHiddenVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | using System.Windows.Data;
3 | using System.Windows.Markup;
4 | using Visibility = System.Windows.Visibility;
5 |
6 | namespace Nice3point.Revit.AddIn.Views.Converters;
7 |
8 | public class EnumVisibilityConverter : MarkupExtension, IValueConverter where TEnum : Enum
9 | {
10 | public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
11 | {
12 | if (value is not TEnum valueEnum)
13 | {
14 | throw new ArgumentException($"{nameof(value)} is not type: {typeof(TEnum)}");
15 | }
16 |
17 | if (parameter is not TEnum parameterEnum)
18 | {
19 | throw new ArgumentException($"{nameof(parameter)} is not type: {typeof(TEnum)}");
20 | }
21 |
22 | return EqualityComparer.Default.Equals(valueEnum, parameterEnum) ? Visibility.Visible : Visibility.Hidden;
23 | }
24 |
25 | public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
26 | {
27 | throw new NotSupportedException();
28 | }
29 |
30 | public override object ProvideValue(IServiceProvider serviceProvider)
31 | {
32 | return this;
33 | }
34 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn/Views/Converters/EnumCollapsedVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | using System.Windows.Data;
3 | using System.Windows.Markup;
4 | using Visibility = System.Windows.Visibility;
5 |
6 | namespace Nice3point.Revit.AddIn.Views.Converters;
7 |
8 | public class EnumCollapsedVisibilityConverter : MarkupExtension, IValueConverter where TEnum : Enum
9 | {
10 | public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
11 | {
12 | if (value is not TEnum valueEnum)
13 | {
14 | throw new ArgumentException($"{nameof(value)} is not type: {typeof(TEnum)}");
15 | }
16 |
17 | if (parameter is not TEnum parameterEnum)
18 | {
19 | throw new ArgumentException($"{nameof(parameter)} is not type: {typeof(TEnum)}");
20 | }
21 |
22 | return EqualityComparer.Default.Equals(valueEnum, parameterEnum) ? Visibility.Visible : Visibility.Collapsed;
23 | }
24 |
25 | public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
26 | {
27 | throw new NotSupportedException();
28 | }
29 |
30 | public override object ProvideValue(IServiceProvider serviceProvider)
31 | {
32 | return this;
33 | }
34 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Module/Views/Converters/EnumCollapsedVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | using System.Windows.Data;
3 | using System.Windows.Markup;
4 | using Visibility = System.Windows.Visibility;
5 |
6 | namespace Nice3point.Revit.AddIn.Views.Converters;
7 |
8 | public class EnumCollapsedVisibilityConverter : MarkupExtension, IValueConverter where TEnum : Enum
9 | {
10 | public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
11 | {
12 | if (value is not TEnum valueEnum)
13 | {
14 | throw new ArgumentException($"{nameof(value)} is not type: {typeof(TEnum)}");
15 | }
16 |
17 | if (parameter is not TEnum parameterEnum)
18 | {
19 | throw new ArgumentException($"{nameof(parameter)} is not type: {typeof(TEnum)}");
20 | }
21 |
22 | return EqualityComparer.Default.Equals(valueEnum, parameterEnum) ? Visibility.Visible : Visibility.Collapsed;
23 | }
24 |
25 | public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
26 | {
27 | throw new NotSupportedException();
28 | }
29 |
30 | public override object ProvideValue(IServiceProvider serviceProvider)
31 | {
32 | return this;
33 | }
34 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn/Views/Converters/EnumBooleanConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | using System.Windows.Data;
3 | using System.Windows.Markup;
4 |
5 | namespace Nice3point.Revit.AddIn.Views.Converters;
6 |
7 | public class EnumBooleanConverter : MarkupExtension, IValueConverter where TEnum : Enum
8 | {
9 | public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
10 | {
11 | if (value is not TEnum valueEnum)
12 | {
13 | throw new ArgumentException($"{nameof(value)} is not type: {typeof(TEnum)}");
14 | }
15 |
16 | if (parameter is not TEnum parameterEnum)
17 | {
18 | throw new ArgumentException($"{nameof(parameter)} is not type: {typeof(TEnum)}");
19 | }
20 |
21 | return EqualityComparer.Default.Equals(valueEnum, parameterEnum);
22 | }
23 |
24 | public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
25 | {
26 | if (parameter is not TEnum parameterEnum)
27 | {
28 | throw new ArgumentException($"{nameof(parameter)} is not type: {typeof(TEnum)}");
29 | }
30 |
31 | return parameterEnum;
32 | }
33 |
34 | public override object ProvideValue(IServiceProvider serviceProvider)
35 | {
36 | return this;
37 | }
38 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Module/Views/Converters/EnumBooleanConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | using System.Windows.Data;
3 | using System.Windows.Markup;
4 |
5 | namespace Nice3point.Revit.AddIn.Views.Converters;
6 |
7 | public class EnumBooleanConverter : MarkupExtension, IValueConverter where TEnum : Enum
8 | {
9 | public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
10 | {
11 | if (value is not TEnum valueEnum)
12 | {
13 | throw new ArgumentException($"{nameof(value)} is not type: {typeof(TEnum)}");
14 | }
15 |
16 | if (parameter is not TEnum parameterEnum)
17 | {
18 | throw new ArgumentException($"{nameof(parameter)} is not type: {typeof(TEnum)}");
19 | }
20 |
21 | return EqualityComparer.Default.Equals(valueEnum, parameterEnum);
22 | }
23 |
24 | public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
25 | {
26 | if (parameter is not TEnum parameterEnum)
27 | {
28 | throw new ArgumentException($"{nameof(parameter)} is not type: {typeof(TEnum)}");
29 | }
30 |
31 | return parameterEnum;
32 | }
33 |
34 | public override object ProvideValue(IServiceProvider serviceProvider)
35 | {
36 | return this;
37 | }
38 | }
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/build/Build.Clean.cs:
--------------------------------------------------------------------------------
1 | using Nuke.Common.Tools.DotNet;
2 | using Nuke.Common.ProjectModel;
3 | using static Nuke.Common.Tools.DotNet.DotNetTasks;
4 |
5 | sealed partial class Build
6 | {
7 | ///
8 | /// Clean projects with dependencies.
9 | ///
10 | Target Clean => _ => _
11 | .OnlyWhenStatic(() => IsLocalBuild)
12 | .Executes(() =>
13 | {
14 | Project[] excludedProjects =
15 | [
16 | Solution.Automation.Build
17 | ];
18 |
19 | CleanDirectory(ArtifactsDirectory);
20 | foreach (var project in Solution.AllProjects)
21 | {
22 | if (excludedProjects.Contains(project)) continue;
23 |
24 | CleanDirectory(project.Directory / "bin");
25 | CleanDirectory(project.Directory / "obj");
26 | }
27 |
28 | foreach (var configuration in GlobBuildConfigurations())
29 | {
30 | DotNetClean(settings => settings
31 | .SetProject(Solution)
32 | .SetConfiguration(configuration)
33 | .SetVerbosity(DotNetVerbosity.minimal)
34 | .EnableNoLogo());
35 | }
36 | });
37 |
38 | ///
39 | /// Clean and log the specified directory.
40 | ///
41 | static void CleanDirectory(AbsolutePath path)
42 | {
43 | Log.Information("Cleaning directory: {Directory}", path);
44 | path.CreateOrCleanDirectory();
45 | }
46 | }
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/source/RevitAddIn/Config/LoggerConfigurator.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.Logging;
2 | using Serilog;
3 | using Serilog.Core;
4 | using Serilog.Events;
5 |
6 | namespace RevitAddIn.Config;
7 |
8 | ///
9 | /// Application logging configuration
10 | ///
11 | ///
12 | ///
13 | /// public class Class(ILogger<Class> logger)
14 | /// {
15 | /// private void Execute()
16 | /// {
17 | /// logger.LogInformation("Message");
18 | /// }
19 | /// }
20 | ///
21 | ///
22 | public static class LoggerConfigurator
23 | {
24 | private const string LogTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] {SourceContext}: {Message:lj}{NewLine}{Exception}";
25 |
26 | public static void AddSerilogConfiguration(this ILoggingBuilder builder)
27 | {
28 | var logger = CreateDefaultLogger();
29 | builder.AddSerilog(logger);
30 |
31 | AppDomain.CurrentDomain.UnhandledException += OnOnUnhandledException;
32 | }
33 |
34 | private static Logger CreateDefaultLogger()
35 | {
36 | return new LoggerConfiguration()
37 | .WriteTo.Debug(LogEventLevel.Debug, LogTemplate)
38 | .MinimumLevel.Debug()
39 | .CreateLogger();
40 | }
41 |
42 | private static void OnOnUnhandledException(object sender, UnhandledExceptionEventArgs args)
43 | {
44 | var exception = (Exception)args.ExceptionObject;
45 | var logger = Host.GetService>();
46 | logger.LogCritical(exception, "Domain unhandled exception");
47 | }
48 | }
--------------------------------------------------------------------------------
/RevitTemplates.sln:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 12.00
2 | # Visual Studio Version 17
3 | VisualStudioVersion = 17.0.31521.260
4 | MinimumVisualStudioVersion = 10.0.40219.1
5 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{54D6B6B5-F661-4B55-B787-46BE8CC5C6A3}"
6 | ProjectSection(SolutionItems) = preProject
7 | Readme.md = Readme.md
8 | .gitignore = .gitignore
9 | Build\Build.Configuration.cs = Build\Build.Configuration.cs
10 | Changelog.md = Changelog.md
11 | EndProjectSection
12 | EndProject
13 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Build", "build\Build.csproj", "{114BF9D5-DD32-468D-9877-4CCB85204598}"
14 | EndProject
15 | Project("{DC6D3A3E-EB5D-4BAD-B47B-17B0A6593D49}") = "RevitTemplates", "source\RevitTemplates.csproj", "{60315C2E-AD1E-45C3-BA42-673DF50DDAD8}"
16 | EndProject
17 | Global
18 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
19 | Release|Any CPU = Release|Any CPU
20 | EndGlobalSection
21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
22 | {60315C2E-AD1E-45C3-BA42-673DF50DDAD8}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {60315C2E-AD1E-45C3-BA42-673DF50DDAD8}.Release|Any CPU.Build.0 = Release|Any CPU
24 | {114BF9D5-DD32-468D-9877-4CCB85204598}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | EndGlobalSection
26 | GlobalSection(RiderSharedRunConfigurations) = postSolution
27 | File = source\Nice3point.Revit.AddIn.Solution\.run\Nuke Clean.run.xml
28 | File = source\Nice3point.Revit.AddIn.Solution\.run\Nuke Plan.run.xml
29 | File = source\Nice3point.Revit.AddIn.Solution\.run\Nuke.run.xml
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Solution/build/Build.Clean.cs:
--------------------------------------------------------------------------------
1 | using Nuke.Common.Tools.DotNet;
2 | using Nuke.Common.ProjectModel;
3 | using static Nuke.Common.Tools.DotNet.DotNetTasks;
4 |
5 | sealed partial class Build
6 | {
7 | ///
8 | /// Clean projects with dependencies.
9 | ///
10 | Target Clean => _ => _
11 | .OnlyWhenStatic(() => IsLocalBuild)
12 | .Executes(() =>
13 | {
14 | Project[] excludedProjects =
15 | [
16 | Solution.Automation.Build
17 | ];
18 |
19 | #if (HasArtifacts)
20 | CleanDirectory(ArtifactsDirectory);
21 | #endif
22 | foreach (var project in Solution.AllProjects)
23 | {
24 | if (excludedProjects.Contains(project)) continue;
25 |
26 | CleanDirectory(project.Directory / "bin");
27 | CleanDirectory(project.Directory / "obj");
28 | }
29 |
30 | foreach (var configuration in GlobBuildConfigurations())
31 | {
32 | DotNetClean(settings => settings
33 | .SetProject(Solution)
34 | .SetConfiguration(configuration)
35 | .SetVerbosity(DotNetVerbosity.minimal)
36 | .EnableNoLogo());
37 | }
38 | });
39 |
40 | ///
41 | /// Clean and log the specified directory.
42 | ///
43 | static void CleanDirectory(AbsolutePath path)
44 | {
45 | Log.Information("Cleaning directory: {Directory}", path);
46 | path.CreateOrCleanDirectory();
47 | }
48 | }
--------------------------------------------------------------------------------
/samples/MultiProjectApplication/Module1/Views/Module1View.xaml:
--------------------------------------------------------------------------------
1 |
15 |
18 |
19 |
20 |
21 |
22 |
23 |
25 |
26 |
27 |
29 |
34 |
43 |
44 |
--------------------------------------------------------------------------------
/samples/MultiProjectApplication/Module2/Views/Module2View.xaml:
--------------------------------------------------------------------------------
1 |
15 |
18 |
19 |
20 |
21 |
22 |
23 |
25 |
26 |
27 |
29 |
34 |
43 |
44 |
--------------------------------------------------------------------------------
/source/RevitTemplates.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net9.0
5 | true
6 | false
7 | true
8 | content
9 | $(NoWarn);NU5128;NU5110;NU5111
10 |
11 |
12 |
13 | Template
14 | Nice3point.Revit.Templates
15 | Nice3point
16 | Templates for Revit add-ins development
17 | revit;templates;addin
18 | git
19 | https://github.com/Nice3point/RevitTemplates
20 | https://github.com/Nice3point/RevitTemplates
21 | images\PackageIcon.png
22 | License.md
23 | Readme.md
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/samples/SingleProjectDIApplication/RevitAddIn/Views/RevitAddInView.xaml:
--------------------------------------------------------------------------------
1 |
15 |
18 |
19 |
20 |
21 |
22 |
23 |
25 |
26 |
27 |
29 |
34 |
43 |
44 |
--------------------------------------------------------------------------------
/samples/SingleProjectHostingApplication/RevitAddIn/Views/RevitAddInView.xaml:
--------------------------------------------------------------------------------
1 |
15 |
18 |
19 |
20 |
21 |
22 |
23 |
25 |
26 |
27 |
29 |
34 |
43 |
44 |
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/source/ModalModule/Views/ModalModuleView.xaml:
--------------------------------------------------------------------------------
1 |
15 |
18 |
19 |
20 |
21 |
22 |
23 |
25 |
26 |
27 |
29 |
34 |
43 |
44 |
--------------------------------------------------------------------------------
/samples/SingleProjectWpfModalApplication/RevitAddIn/Views/RevitAddInView.xaml:
--------------------------------------------------------------------------------
1 |
15 |
18 |
19 |
20 |
21 |
22 |
23 |
25 |
26 |
27 |
29 |
34 |
43 |
44 |
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/source/ModelessModule/Services/ModelessController.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 | using Visibility = System.Windows.Visibility;
3 |
4 | namespace ModelessModule.Services;
5 |
6 | public sealed class ModelessController
7 | {
8 | private Window _window;
9 |
10 | ///
11 | /// Attempts to set focus to this element
12 | ///
13 | /// True if the window instance has already been created
14 | public bool Focus()
15 | {
16 | if (_window.WindowState == WindowState.Minimized) _window.WindowState = WindowState.Normal;
17 | if (_window.Visibility != Visibility.Visible) _window.Show();
18 | return _window.Focus();
19 | }
20 |
21 | /// Opens a window and returns without waiting for the newly opened _window to close
22 | public void Show(Window window)
23 | {
24 | RegisterWindow(window);
25 | window.Show(Context.UiApplication.MainWindowHandle);
26 | }
27 |
28 | ///
29 | /// Makes an active window visible
30 | ///
31 | public void Show()
32 | {
33 | _window?.Show();
34 | }
35 |
36 | ///
37 | /// Makes an active window invisible
38 | ///
39 | public void Hide()
40 | {
41 | _window?.Hide();
42 | }
43 |
44 | ///
45 | /// Manually closes an active window />
46 | ///
47 | public void Close()
48 | {
49 | _window?.Close();
50 | }
51 |
52 | private void RegisterWindow(Window window)
53 | {
54 | _window = window;
55 | _window.Closed += (_, _) =>
56 | {
57 | _window = null;
58 | };
59 | }
60 | }
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | ## Create your Add-In for Revit on the .Net platform
9 |
10 | [](https://www.nuget.org/packages/Nice3point.Revit.Templates)
11 | [](https://www.nuget.org/packages/Nice3point.Revit.Templates)
12 | [](https://github.com/Nice3point/RevitTemplate/commits/develop)
13 |
14 | This repository contains a project templates for creating Revit Add-In.
15 |
16 | ## Template Features
17 |
18 | - Revit multi-version support.
19 | - Publishing GitHub releases.
20 | - Creating a multi-version installers.
21 | - MVVM pattern with Modal and Modeless windows.
22 | - Creating a bundle for publishing to the Autodesk Store.
23 | - Application and Command add-in types.
24 | - GitHub Actions and Azure DevOps pipelines.
25 | - Dependency Injection.
26 | - Add-in logging.
27 |
28 | ## Installation
29 |
30 | 1. Install the latest [.Net SDK](https://dotnet.microsoft.com/download).
31 | 2. Run `dotnet new install Nice3point.Revit.Templates` to install the project templates.
32 |
33 | ## Usage
34 |
35 | - To create a project use the IDE or run `dotnet new`.
36 | - For more information, read [Wiki](https://github.com/Nice3point/RevitTemplates/wiki).
37 |
--------------------------------------------------------------------------------
/samples/SingleProjectHostingApplication/RevitAddIn/Host.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using System.Reflection;
3 | using Microsoft.Extensions.Hosting;
4 | using Microsoft.Extensions.DependencyInjection;
5 | using RevitAddIn.Views;
6 | using RevitAddIn.ViewModels;
7 |
8 | namespace RevitAddIn;
9 |
10 | ///
11 | /// Provides a host for the application's services and manages their lifetimes
12 | ///
13 | public static class Host
14 | {
15 | private static IHost _host;
16 |
17 | ///
18 | /// Starts the host and configures the application's services
19 | ///
20 | public static void Start()
21 | {
22 | var builder = new HostApplicationBuilder(new HostApplicationBuilderSettings
23 | {
24 | ContentRootPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
25 | DisableDefaults = true
26 | });
27 |
28 | builder.Services.AddTransient();
29 | builder.Services.AddTransient();
30 |
31 | _host = builder.Build();
32 | _host.Start();
33 | }
34 |
35 | ///
36 | /// Stops the host and handle services
37 | ///
38 | public static void Stop()
39 | {
40 | _host.StopAsync().GetAwaiter().GetResult();
41 | }
42 |
43 | ///
44 | /// Get service of type
45 | ///
46 | /// The type of service object to get
47 | /// There is no service of type
48 | public static T GetService() where T : class
49 | {
50 | return _host.Services.GetRequiredService();
51 | }
52 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Solution/azure-pipelines.yml:
--------------------------------------------------------------------------------
1 | trigger:
2 | tags:
3 | include:
4 | - '*'
5 |
6 | pr: none
7 |
8 | parameters:
9 | - name: version
10 | displayName: "Release version"
11 | type: string
12 | default: ""
13 |
14 | jobs:
15 | - job: PublishRelease
16 | displayName: "Publish release"
17 | pool:
18 | vmImage: "windows-2022"
19 | steps:
20 | - checkout: self
21 | persistCredentials: true
22 | fetchDepth: 0
23 |
24 | - script: |
25 | git tag ${{ parameters.version }}
26 | git push origin ${{ parameters.version }}
27 | displayName: "Create release tag"
28 | condition: and(succeeded(), ne('${{ parameters.version }}', ''))
29 |
30 | - task: Cache@2
31 | displayName: "Cache packages"
32 | inputs:
33 | key: $(Agent.OS) | nuget-packages | global.json, **/*.csproj, **/Directory.Packages.props
34 | restoreKeys: $(Agent.OS) | nuget-packages
35 | path: ~/.nuget/packages
36 |
37 | - script: |
38 | set RELEASE_VERSION=${{ parameters.version }}
39 | if "${{ parameters.version }}"=="" set RELEASE_VERSION=$(Build.SourceBranchName)
40 | #if (bundle && installer)
41 | ./.nuke/build.cmd CreateBundle CreateInstaller --ReleaseVersion %RELEASE_VERSION%
42 | #elseif (installer)
43 | ./.nuke/build.cmd CreateInstaller --ReleaseVersion %RELEASE_VERSION%
44 | #elseif (bundle)
45 | ./.nuke/build.cmd CreateBundle --ReleaseVersion %RELEASE_VERSION%
46 | #else
47 | ./.nuke/build.cmd --ReleaseVersion %RELEASE_VERSION%
48 | #endif
49 | displayName: "Publish release"
50 |
51 | - task: PublishBuildArtifacts@1
52 | inputs:
53 | ArtifactName: Nice3point.Revit.AddIn
54 | PathtoPublish: 'output'
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/install/Installer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Installer;
3 | using WixSharp;
4 | using WixSharp.CommonTasks;
5 | using WixSharp.Controls;
6 | using Assembly = System.Reflection.Assembly;
7 |
8 | const string outputName = "MultiProjectSolution";
9 | const string projectName = "MultiProjectSolution";
10 |
11 | var project = new Project
12 | {
13 | OutDir = "output",
14 | Name = projectName,
15 | Platform = Platform.x64,
16 | UI = WUI.WixUI_FeatureTree,
17 | MajorUpgrade = MajorUpgrade.Default,
18 | GUID = new Guid("235D1107-BED9-48BA-9D2F-37B4B046C071"),
19 | BannerImage = @"install\Resources\Icons\BannerImage.png",
20 | BackgroundImage = @"install\Resources\Icons\BackgroundImage.png",
21 | Version = Assembly.GetExecutingAssembly().GetName().Version.ClearRevision(),
22 | ControlPanelInfo =
23 | {
24 | Manufacturer = Environment.UserName,
25 | ProductIcon = @"install\Resources\Icons\ShellIcon.ico"
26 | }
27 | };
28 |
29 | var wixEntities = Generator.GenerateWixEntities(args);
30 | project.RemoveDialogsBetween(NativeDialogs.WelcomeDlg, NativeDialogs.CustomizeDlg);
31 |
32 | BuildSingleUserMsi();
33 | BuildMultiUserUserMsi();
34 |
35 | void BuildSingleUserMsi()
36 | {
37 | project.InstallScope = InstallScope.perUser;
38 | project.OutFileName = $"{outputName}-{project.Version}-SingleUser";
39 | project.Dirs =
40 | [
41 | new InstallDir(@"%AppDataFolder%\Autodesk\Revit\Addins\", wixEntities)
42 | ];
43 | project.BuildMsi();
44 | }
45 |
46 | void BuildMultiUserUserMsi()
47 | {
48 | project.InstallScope = InstallScope.perMachine;
49 | project.OutFileName = $"{outputName}-{project.Version}-MultiUser";
50 | project.Dirs =
51 | [
52 | new InstallDir(@"%CommonAppDataFolder%\Autodesk\Revit\Addins\", wixEntities)
53 | ];
54 | project.BuildMsi();
55 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Solution/install/Installer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Installer;
3 | using WixSharp;
4 | using WixSharp.CommonTasks;
5 | using WixSharp.Controls;
6 | using Assembly = System.Reflection.Assembly;
7 |
8 | const string outputName = "Nice3point.Revit.AddIn";
9 | const string projectName = "Nice3point.Revit.AddIn";
10 |
11 | var project = new Project
12 | {
13 | OutDir = "output",
14 | Name = projectName,
15 | Platform = Platform.x64,
16 | UI = WUI.WixUI_FeatureTree,
17 | MajorUpgrade = MajorUpgrade.Default,
18 | GUID = new Guid("DDDDDDDD-DDDD-DDDD-DDDD-DDDDDDDDDDDD"),
19 | BannerImage = @"install\Resources\Icons\BannerImage.png",
20 | BackgroundImage = @"install\Resources\Icons\BackgroundImage.png",
21 | Version = Assembly.GetExecutingAssembly().GetName().Version.ClearRevision(),
22 | ControlPanelInfo =
23 | {
24 | Manufacturer = Environment.UserName,
25 | ProductIcon = @"install\Resources\Icons\ShellIcon.ico"
26 | }
27 | };
28 |
29 | var wixEntities = Generator.GenerateWixEntities(args);
30 | project.RemoveDialogsBetween(NativeDialogs.WelcomeDlg, NativeDialogs.CustomizeDlg);
31 |
32 | BuildSingleUserMsi();
33 | BuildMultiUserUserMsi();
34 |
35 | void BuildSingleUserMsi()
36 | {
37 | project.InstallScope = InstallScope.perUser;
38 | project.OutFileName = $"{outputName}-{project.Version}-SingleUser";
39 | project.Dirs =
40 | [
41 | new InstallDir(@"%AppDataFolder%\Autodesk\Revit\Addins\", wixEntities)
42 | ];
43 | project.BuildMsi();
44 | }
45 |
46 | void BuildMultiUserUserMsi()
47 | {
48 | project.InstallScope = InstallScope.perMachine;
49 | project.OutFileName = $"{outputName}-{project.Version}-MultiUser";
50 | project.Dirs =
51 | [
52 | new InstallDir(@"%CommonAppDataFolder%\Autodesk\Revit\Addins\", wixEntities)
53 | ];
54 | project.BuildMsi();
55 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn/Application.cs:
--------------------------------------------------------------------------------
1 | using Nice3point.Revit.Toolkit.External;
2 | using Nice3point.Revit.AddIn.Commands;
3 | #if (log && !UseIoc)
4 | using Serilog;
5 | using Serilog.Events;
6 | #endif
7 |
8 | namespace Nice3point.Revit.AddIn;
9 |
10 | ///
11 | /// Application entry point
12 | ///
13 | [UsedImplicitly]
14 | public class Application : ExternalApplication
15 | {
16 | public override void OnStartup()
17 | {
18 | #if (UseIoc)
19 | Host.Start();
20 | #endif
21 | #if (log && !UseIoc)
22 | CreateLogger();
23 | #endif
24 | CreateRibbon();
25 | }
26 | #if (Hosting || (!UseIoc && log))
27 |
28 | public override void OnShutdown()
29 | {
30 | #if (Hosting)
31 | Host.Stop();
32 | #elseif (log)
33 | Log.CloseAndFlush();
34 | #endif
35 | }
36 | #endif
37 |
38 | private void CreateRibbon()
39 | {
40 | var panel = Application.CreatePanel("Commands", "Nice3point.Revit.AddIn");
41 |
42 | panel.AddPushButton("Execute")
43 | .SetImage("/Nice3point.Revit.AddIn;component/Resources/Icons/RibbonIcon16.png")
44 | .SetLargeImage("/Nice3point.Revit.AddIn;component/Resources/Icons/RibbonIcon32.png");
45 | }
46 | #if (log && !UseIoc)
47 |
48 | private static void CreateLogger()
49 | {
50 | const string outputTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] {Message:lj}{NewLine}{Exception}";
51 |
52 | Log.Logger = new LoggerConfiguration()
53 | .WriteTo.Debug(LogEventLevel.Debug, outputTemplate)
54 | .MinimumLevel.Debug()
55 | .CreateLogger();
56 |
57 | AppDomain.CurrentDomain.UnhandledException += (_, args) =>
58 | {
59 | var exception = (Exception)args.ExceptionObject;
60 | Log.Fatal(exception, "Domain unhandled exception");
61 | };
62 | }
63 | #endif
64 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Application/Application.cs:
--------------------------------------------------------------------------------
1 | using Nice3point.Revit.Toolkit.External;
2 | using Nice3point.Revit.AddIn.Commands;
3 | #if (log && !UseIoc)
4 | using Serilog;
5 | using Serilog.Events;
6 | #endif
7 |
8 | namespace Nice3point.Revit.AddIn;
9 |
10 | ///
11 | /// Application entry point
12 | ///
13 | [UsedImplicitly]
14 | public class Application : ExternalApplication
15 | {
16 | public override void OnStartup()
17 | {
18 | #if (UseIoc)
19 | Host.Start();
20 | #endif
21 | #if (log && !UseIoc)
22 | CreateLogger();
23 | #endif
24 | CreateRibbon();
25 | }
26 | #if (Hosting || (!UseIoc && log))
27 |
28 | public override void OnShutdown()
29 | {
30 | #if (Hosting)
31 | Host.Stop();
32 | #elseif (log)
33 | Log.CloseAndFlush();
34 | #endif
35 | }
36 | #endif
37 |
38 | private void CreateRibbon()
39 | {
40 | var panel = Application.CreatePanel("Commands", "Nice3point.Revit.AddIn");
41 |
42 | panel.AddPushButton("Execute")
43 | .SetImage("/Nice3point.Revit.AddIn;component/Resources/Icons/RibbonIcon16.png")
44 | .SetLargeImage("/Nice3point.Revit.AddIn;component/Resources/Icons/RibbonIcon32.png");
45 | }
46 | #if (log && !UseIoc)
47 |
48 | private static void CreateLogger()
49 | {
50 | const string outputTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] {Message:lj}{NewLine}{Exception}";
51 |
52 | Log.Logger = new LoggerConfiguration()
53 | .WriteTo.Debug(LogEventLevel.Debug, outputTemplate)
54 | .MinimumLevel.Debug()
55 | .CreateLogger();
56 |
57 | AppDomain.CurrentDomain.UnhandledException += (_, args) =>
58 | {
59 | var exception = (Exception)args.ExceptionObject;
60 | Log.Fatal(exception, "Domain unhandled exception");
61 | };
62 | }
63 | #endif
64 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn/Views/Converters/StringVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | // Copyright 2003-2024 by Autodesk, Inc.
2 | //
3 | // Permission to use, copy, modify, and distribute this software in
4 | // object code form for any purpose and without fee is hereby granted,
5 | // provided that the above copyright notice appears in all copies and
6 | // that both that copyright notice and the limited warranty and
7 | // restricted rights notice below appear in all supporting
8 | // documentation.
9 | //
10 | // AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
11 | // AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
12 | // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
13 | // DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
14 | // UNINTERRUPTED OR ERROR FREE.
15 | //
16 | // Use, duplication, or disclosure by the U.S. Government is subject to
17 | // restrictions set forth in FAR 52.227-19 (Commercial Computer
18 | // Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
19 | // (Rights in Technical Data and Computer Software), as applicable.
20 |
21 | using System.Globalization;
22 | using System.Windows.Data;
23 | using System.Windows.Markup;
24 | using Visibility = System.Windows.Visibility;
25 |
26 | namespace Nice3point.Revit.AddIn.Views.Converters;
27 |
28 | public sealed class StringVisibilityConverter : MarkupExtension, IValueConverter
29 | {
30 | public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
31 | {
32 | if (value is not string text) return Visibility.Collapsed;
33 | return string.IsNullOrEmpty(text) ? Visibility.Collapsed : Visibility.Visible;
34 | }
35 |
36 | public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
37 | {
38 | throw new NotSupportedException();
39 | }
40 |
41 | public override object ProvideValue(IServiceProvider serviceProvider)
42 | {
43 | return this;
44 | }
45 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Module/Views/Converters/StringVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | // Copyright 2003-2024 by Autodesk, Inc.
2 | //
3 | // Permission to use, copy, modify, and distribute this software in
4 | // object code form for any purpose and without fee is hereby granted,
5 | // provided that the above copyright notice appears in all copies and
6 | // that both that copyright notice and the limited warranty and
7 | // restricted rights notice below appear in all supporting
8 | // documentation.
9 | //
10 | // AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
11 | // AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
12 | // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
13 | // DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
14 | // UNINTERRUPTED OR ERROR FREE.
15 | //
16 | // Use, duplication, or disclosure by the U.S. Government is subject to
17 | // restrictions set forth in FAR 52.227-19 (Commercial Computer
18 | // Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
19 | // (Rights in Technical Data and Computer Software), as applicable.
20 |
21 | using System.Globalization;
22 | using System.Windows.Data;
23 | using System.Windows.Markup;
24 | using Visibility = System.Windows.Visibility;
25 |
26 | namespace Nice3point.Revit.AddIn.Views.Converters;
27 |
28 | public sealed class StringVisibilityConverter : MarkupExtension, IValueConverter
29 | {
30 | public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
31 | {
32 | if (value is not string text) return Visibility.Collapsed;
33 | return string.IsNullOrEmpty(text) ? Visibility.Collapsed : Visibility.Visible;
34 | }
35 |
36 | public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
37 | {
38 | throw new NotSupportedException();
39 | }
40 |
41 | public override object ProvideValue(IServiceProvider serviceProvider)
42 | {
43 | return this;
44 | }
45 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn/Commands/StartupCommand.cs:
--------------------------------------------------------------------------------
1 | using Autodesk.Revit.Attributes;
2 | using Nice3point.Revit.Toolkit.External;
3 | #if (NoWindow)
4 | using Autodesk.Revit.UI;
5 | #endif
6 | #if (!NoWindow && !UseIoc)
7 | using Nice3point.Revit.AddIn.ViewModels;
8 | #endif
9 | #if (!NoWindow)
10 | using Nice3point.Revit.AddIn.Views;
11 | #endif
12 | #if (log && Command && !UseIoc)
13 | using Serilog;
14 | using Serilog.Events;
15 | #endif
16 |
17 | namespace Nice3point.Revit.AddIn.Commands;
18 |
19 | ///
20 | /// External command entry point
21 | ///
22 | [UsedImplicitly]
23 | [Transaction(TransactionMode.Manual)]
24 | public class StartupCommand : ExternalCommand
25 | {
26 | public override void Execute()
27 | {
28 | #if (log && Command && !UseIoc)
29 | var logger = CreateLogger();
30 | #endif
31 | #if (Modeless && UseIoc)
32 | var view = Host.GetService();
33 | view.Show(UiApplication.MainWindowHandle);
34 | #elseif (Modal && UseIoc)
35 | var view = Host.GetService();
36 | view.ShowDialog();
37 | #elseif (NoWindow && UseIoc)
38 | TaskDialog.Show(Document.Title, "Nice3point.Revit.AddIn");
39 | #elseif (Modeless)
40 | var viewModel = new Nice3point.Revit.AddInViewModel();
41 | var view = new Nice3point.Revit.AddInView(viewModel);
42 | view.Show(UiApplication.MainWindowHandle);
43 | #elseif (Modal)
44 | var viewModel = new Nice3point.Revit.AddInViewModel();
45 | var view = new Nice3point.Revit.AddInView(viewModel);
46 | view.ShowDialog();
47 | #elseif (NoWindow)
48 | TaskDialog.Show(Document.Title, "Nice3point.Revit.AddIn");
49 | #endif
50 | }
51 | #if (log && Command && !UseIoc)
52 |
53 | private static ILogger CreateLogger()
54 | {
55 | const string outputTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] {Message:lj}{NewLine}{Exception}";
56 |
57 | return new LoggerConfiguration()
58 | .WriteTo.Debug(LogEventLevel.Debug, outputTemplate)
59 | .MinimumLevel.Debug()
60 | .CreateLogger();
61 | }
62 | #endif
63 | }
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/build/Build.Publish.GitHub.cs:
--------------------------------------------------------------------------------
1 | using Nuke.Common.Tools.GitHub;
2 | using Octokit;
3 |
4 | sealed partial class Build
5 | {
6 | ///
7 | /// Publish a new GitHub release.
8 | ///
9 | Target PublishGitHub => _ => _
10 | .DependsOn(CreateInstaller, CreateBundle)
11 | .Requires(() => ReleaseVersion)
12 | .OnlyWhenStatic(() => IsServerBuild)
13 | .Executes(async () =>
14 | {
15 | var gitHubName = GitRepository.GetGitHubName();
16 | var gitHubOwner = GitRepository.GetGitHubOwner();
17 |
18 | var artifacts = Directory.GetFiles(ArtifactsDirectory, "*");
19 | Assert.NotEmpty(artifacts, "No artifacts were found to create the Release");
20 |
21 | var changelogBuilder = CreateChangelogBuilder();
22 | WriteGitHubCompareUrl(changelogBuilder);
23 |
24 | var newRelease = new NewRelease(ReleaseVersion)
25 | {
26 | Name = ReleaseVersion,
27 | Body = changelogBuilder.ToString(),
28 | TargetCommitish = GitRepository.Commit,
29 | Prerelease = IsPrerelease
30 | };
31 |
32 | var release = await GitHubTasks.GitHubClient.Repository.Release.Create(gitHubOwner, gitHubName, newRelease);
33 | await UploadArtifactsAsync(release, artifacts);
34 | });
35 |
36 | ///
37 | /// Uploads the artifacts to the GitHub release.
38 | ///
39 | static async Task UploadArtifactsAsync(Release createdRelease, IEnumerable artifacts)
40 | {
41 | foreach (var file in artifacts)
42 | {
43 | var releaseAssetUpload = new ReleaseAssetUpload
44 | {
45 | ContentType = "application/x-binary",
46 | FileName = Path.GetFileName(file),
47 | RawData = File.OpenRead(file)
48 | };
49 |
50 | await GitHubTasks.GitHubClient.Repository.Release.UploadAsset(createdRelease, releaseAssetUpload);
51 | Log.Information("Artifact: {Path}", file);
52 | }
53 | }
54 | }
--------------------------------------------------------------------------------
/samples/MultiProjectApplication/Module3/Module3.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | latest
5 | x64
6 | true
7 | Debug R20;Debug R21;Debug R22;Debug R23;Debug R24;Debug R25
8 | $(Configurations);Release R20;Release R21;Release R22;Release R23;Release R24;Release R25
9 |
10 |
11 |
12 |
13 | 2020
14 | net48
15 |
16 |
17 | 2021
18 | net48
19 |
20 |
21 | 2022
22 | net48
23 |
24 |
25 | 2023
26 | net48
27 |
28 |
29 | 2024
30 | net48
31 |
32 |
33 | 2025
34 | net8.0-windows
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Solution/build/Build.Publish.GitHub.cs:
--------------------------------------------------------------------------------
1 | using Nuke.Common.Tools.GitHub;
2 | using Octokit;
3 |
4 | sealed partial class Build
5 | {
6 | ///
7 | /// Publish a new GitHub release.
8 | ///
9 | Target PublishGitHub => _ => _
10 | #if (installer && bundle)
11 | .DependsOn(CreateInstaller, CreateBundle)
12 | #elseif (installer)
13 | .DependsOn(CreateInstaller)
14 | #elseif (bundle)
15 | .DependsOn(CreateBundle)
16 | #else
17 | .DependsOn(Compile)
18 | #endif
19 | .Requires(() => ReleaseVersion)
20 | .OnlyWhenStatic(() => IsServerBuild)
21 | .Executes(async () =>
22 | {
23 | var gitHubName = GitRepository.GetGitHubName();
24 | var gitHubOwner = GitRepository.GetGitHubOwner();
25 |
26 | var artifacts = Directory.GetFiles(ArtifactsDirectory, "*");
27 | Assert.NotEmpty(artifacts, "No artifacts were found to create the Release");
28 |
29 | var changelogBuilder = CreateChangelogBuilder();
30 | WriteGitHubCompareUrl(changelogBuilder);
31 |
32 | var newRelease = new NewRelease(ReleaseVersion)
33 | {
34 | Name = ReleaseVersion,
35 | Body = changelogBuilder.ToString(),
36 | TargetCommitish = GitRepository.Commit,
37 | Prerelease = IsPrerelease
38 | };
39 |
40 | var release = await GitHubTasks.GitHubClient.Repository.Release.Create(gitHubOwner, gitHubName, newRelease);
41 | await UploadArtifactsAsync(release, artifacts);
42 | });
43 |
44 | ///
45 | /// Uploads the artifacts to the GitHub release.
46 | ///
47 | static async Task UploadArtifactsAsync(Release createdRelease, IEnumerable artifacts)
48 | {
49 | foreach (var file in artifacts)
50 | {
51 | var releaseAssetUpload = new ReleaseAssetUpload
52 | {
53 | ContentType = "application/x-binary",
54 | FileName = Path.GetFileName(file),
55 | RawData = File.OpenRead(file)
56 | };
57 |
58 | await GitHubTasks.GitHubClient.Repository.Release.UploadAsset(createdRelease, releaseAssetUpload);
59 | Log.Information("Artifact: {Path}", file);
60 | }
61 | }
62 | }
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/source/RevitAddIn/Host.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using System.Reflection;
3 | using Microsoft.Extensions.DependencyInjection;
4 | using Microsoft.Extensions.Hosting;
5 | using Microsoft.Extensions.Logging;
6 | using ModalModule.ViewModels;
7 | using ModalModule.Views;
8 | using ModelessModule.Services;
9 | using ModelessModule.ViewModels;
10 | using ModelessModule.Views;
11 | using RevitAddIn.Config;
12 |
13 | namespace RevitAddIn;
14 |
15 | ///
16 | /// Provides a host for the application's services and manages their lifetimes
17 | ///
18 | public static class Host
19 | {
20 | private static IHost _host;
21 |
22 | ///
23 | /// Starts the host and configures the application's services
24 | ///
25 | public static void Start()
26 | {
27 | var builder = new HostApplicationBuilder(new HostApplicationBuilderSettings
28 | {
29 | ContentRootPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
30 | DisableDefaults = true
31 | });
32 |
33 | //Logging
34 | builder.Logging.ClearProviders();
35 | builder.Logging.AddSerilogConfiguration();
36 |
37 | //Configuration
38 | builder.Services.AddSerializerOptions();
39 |
40 | //Services
41 | builder.Services.AddSingleton();
42 | builder.Services.AddTransient();
43 | builder.Services.AddTransient();
44 | builder.Services.AddTransient();
45 | builder.Services.AddTransient();
46 |
47 | _host = builder.Build();
48 | _host.Start();
49 | }
50 |
51 | ///
52 | /// Stops the host and handle services
53 | ///
54 | public static void Stop()
55 | {
56 | _host.StopAsync().GetAwaiter().GetResult();
57 | }
58 |
59 | ///
60 | /// Get service of type
61 | ///
62 | /// The type of service object to get
63 | /// There is no service of type
64 | public static T GetService() where T : class
65 | {
66 | return _host.Services.GetRequiredService();
67 | }
68 | }
--------------------------------------------------------------------------------
/samples/MultiProjectApplication/Module2/Module2.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | true
5 | latest
6 | x64
7 | true
8 | Debug R20;Debug R21;Debug R22;Debug R23;Debug R24;Debug R25
9 | $(Configurations);Release R20;Release R21;Release R22;Release R23;Release R24;Release R25
10 |
11 |
12 |
13 |
14 | 2020
15 | net48
16 |
17 |
18 | 2021
19 | net48
20 |
21 |
22 | 2022
23 | net48
24 |
25 |
26 | 2023
27 | net48
28 |
29 |
30 | 2024
31 | net48
32 |
33 |
34 | 2025
35 | net8.0-windows
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/samples/MultiProjectApplication/Module1/Module1.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | true
5 | latest
6 | x64
7 | true
8 | Debug R20;Debug R21;Debug R22;Debug R23;Debug R24;Debug R25
9 | $(Configurations);Release R20;Release R21;Release R22;Release R23;Release R24;Release R25
10 |
11 |
12 |
13 |
14 | 2020
15 | net48
16 |
17 |
18 | 2021
19 | net48
20 |
21 |
22 | 2022
23 | net48
24 |
25 |
26 | 2023
27 | net48
28 |
29 |
30 | 2024
31 | net48
32 |
33 |
34 | 2025
35 | net8.0-windows
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Application/Host.cs:
--------------------------------------------------------------------------------
1 | #if (Hosting)
2 | using System.IO;
3 | using System.Reflection;
4 | using Microsoft.Extensions.Hosting;
5 | using Nice3point.Revit.AddIn.Config.Options;
6 | #endif
7 | #if (log && Hosting)
8 | using Microsoft.Extensions.Logging;
9 | #endif
10 | using Microsoft.Extensions.DependencyInjection;
11 | #if (log && UseIoc)
12 | using Nice3point.Revit.AddIn.Config.Logging;
13 | #endif
14 |
15 | namespace Nice3point.Revit.AddIn;
16 |
17 | ///
18 | /// Provides a host for the application's services and manages their lifetimes
19 | ///
20 | public static class Host
21 | {
22 | #if (Container)
23 | private static IServiceProvider? _serviceProvider;
24 | #endif
25 | #if (Hosting)
26 | private static IHost? _host;
27 | #endif
28 |
29 | ///
30 | /// Starts the host and configures the application's services
31 | ///
32 | public static void Start()
33 | {
34 | #if (Container)
35 | var services = new ServiceCollection();
36 | #if (log)
37 |
38 | //Logging
39 | services.AddSerilogConfiguration();
40 | #endif
41 |
42 | _serviceProvider = services.BuildServiceProvider();
43 | #endif
44 | #if (Hosting)
45 | var builder = new HostApplicationBuilder(new HostApplicationBuilderSettings
46 | {
47 | ContentRootPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
48 | DisableDefaults = true
49 | });
50 | #if (log)
51 |
52 | //Logging
53 | builder.Logging.ClearProviders();
54 | builder.Logging.AddSerilogConfiguration();
55 | #endif
56 |
57 | //Options
58 | builder.Services.AddApplicationOptions();
59 |
60 | _host = builder.Build();
61 | _host.Start();
62 | #endif
63 | }
64 | #if (Hosting)
65 |
66 | ///
67 | /// Stops the host and handle services
68 | ///
69 | public static void Stop()
70 | {
71 | _host!.StopAsync().GetAwaiter().GetResult();
72 | }
73 | #endif
74 |
75 | ///
76 | /// Get service of type
77 | ///
78 | /// The type of service object to get
79 | /// There is no service of type
80 | public static T GetService() where T : class
81 | {
82 | #if (Container)
83 | return _serviceProvider!.GetRequiredService();
84 | #endif
85 | #if (Hosting)
86 | return _host!.Services.GetRequiredService();
87 | #endif
88 | }
89 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Module/Nice3point.Revit.AddIn.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | true
6 |
7 | enable
8 | latest
9 | x64
10 | true
11 | Debug R21;Debug R22;Debug R23;Debug R24;Debug R25;Debug R26
12 | $(Configurations);Release R21;Release R22;Release R23;Release R24;Release R25;Release R26
13 |
14 |
15 |
16 |
17 | 2021
18 | net48
19 |
20 |
21 | 2022
22 | net48
23 |
24 |
25 | 2023
26 | net48
27 |
28 |
29 | 2024
30 | net48
31 |
32 |
33 | 2025
34 | net8.0-windows
35 |
36 |
37 | 2026
38 | net8.0-windows
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/source/ModelessModule/ModelessModule.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | true
5 | latest
6 | x64
7 | true
8 | Debug R20;Debug R21;Debug R22;Debug R23;Debug R24;Debug R25
9 | $(Configurations);Release R20;Release R21;Release R22;Release R23;Release R24;Release R25
10 |
11 |
12 |
13 |
14 | 2020
15 | net48
16 |
17 |
18 | 2021
19 | net48
20 |
21 |
22 | 2022
23 | net48
24 |
25 |
26 | 2023
27 | net48
28 |
29 |
30 | 2024
31 | net48
32 |
33 |
34 | 2025
35 | net8.0-windows
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/build/Build.Changelog.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using Nuke.Common.Tools.Git;
3 | using Nuke.Common.Tools.GitHub;
4 |
5 | sealed partial class Build
6 | {
7 | ///
8 | /// Creates a Builder for creating a changelog for the current release.
9 | ///
10 | StringBuilder CreateChangelogBuilder()
11 | {
12 | Assert.True(File.Exists(ChangelogPath), $"Unable to locate the changelog file: {ChangelogPath}");
13 | Log.Information("Changelog: {Path}", ChangelogPath);
14 |
15 | var changelog = BuildChangelog();
16 | Assert.True(changelog.Length > 0, $"No version entry exists in the changelog: {ReleaseVersion}");
17 |
18 | return changelog;
19 | }
20 |
21 | ///
22 | /// Appends the GitHub compare URL to the changelog builder.
23 | ///
24 | void WriteGitHubCompareUrl(StringBuilder changelogBuilder)
25 | {
26 | var tags = GitTasks
27 | .Git("tag -l --sort=v:refname", logInvocation: false, logOutput: false)
28 | .ToArray();
29 |
30 | if (tags.Length < 2) return;
31 |
32 | if (changelogBuilder[^1] != '\r' || changelogBuilder[^1] != '\n') changelogBuilder.AppendLine(Environment.NewLine);
33 | changelogBuilder.Append("Full changelog: ");
34 | changelogBuilder.Append(GitRepository.GetGitHubCompareTagsUrl(tags[^1].Text, tags[^2].Text));
35 | }
36 |
37 | ///
38 | /// Builds the changelog content for the current release.
39 | ///
40 | StringBuilder BuildChangelog()
41 | {
42 | const string separator = "# ";
43 |
44 | var hasEntry = false;
45 | var changelog = new StringBuilder();
46 | foreach (var line in File.ReadLines(ChangelogPath))
47 | {
48 | if (hasEntry)
49 | {
50 | if (line.StartsWith(separator)) break;
51 |
52 | changelog.AppendLine(line);
53 | continue;
54 | }
55 |
56 | if (line.StartsWith(separator) && line.Contains(ReleaseVersion))
57 | {
58 | hasEntry = true;
59 | }
60 | }
61 |
62 | TrimEmptyLines(changelog);
63 | return changelog;
64 | }
65 |
66 | ///
67 | /// Trims empty lines from the changelog builder.
68 | ///
69 | static void TrimEmptyLines(StringBuilder builder)
70 | {
71 | if (builder.Length == 0) return;
72 |
73 | while (builder[^1] == '\r' || builder[^1] == '\n')
74 | {
75 | builder.Remove(builder.Length - 1, 1);
76 | }
77 |
78 | while (builder[0] == '\r' || builder[0] == '\n')
79 | {
80 | builder.Remove(0, 1);
81 | }
82 | }
83 | }
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/install/Installer.Generator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Text.RegularExpressions;
6 | using WixSharp;
7 |
8 | namespace Installer;
9 |
10 | public static class Generator
11 | {
12 | ///
13 | /// Generates Wix entities, features and directories for the installer.
14 | ///
15 | public static WixEntity[] GenerateWixEntities(IEnumerable args)
16 | {
17 | var versionRegex = new Regex(@"\d+");
18 | var versionStorages = new Dictionary>();
19 |
20 | var revitFeature = new Feature
21 | {
22 | Name = "Revit Add-in",
23 | Description = "Revit add-in installation files",
24 | Display = FeatureDisplay.expand
25 | };
26 |
27 | foreach (var directory in args)
28 | {
29 | var directoryInfo = new DirectoryInfo(directory);
30 | var fileVersion = versionRegex.Match(directoryInfo.Name).Value;
31 | var feature = new Feature
32 | {
33 | Name = fileVersion,
34 | Description = $"Install add-in for Revit {fileVersion}",
35 | ConfigurableDir = $"INSTALL{fileVersion}"
36 | };
37 |
38 | revitFeature.Add(feature);
39 |
40 | var files = new Files(feature, $@"{directory}\*.*", FilterEntities);
41 | if (versionStorages.TryGetValue(fileVersion, out var storage))
42 | {
43 | storage.Add(files);
44 | }
45 | else
46 | {
47 | versionStorages.Add(fileVersion, [files]);
48 | }
49 |
50 | LogFeatureFiles(directory, fileVersion);
51 | }
52 |
53 | return versionStorages
54 | .Select(storage => new Dir(new Id($"INSTALL{storage.Key}"), storage.Key, storage.Value.ToArray()))
55 | .Cast()
56 | .ToArray();
57 | }
58 |
59 | ///
60 | /// Filter installer files and exclude from output.
61 | ///
62 | private static bool FilterEntities(string file)
63 | {
64 | return !file.EndsWith(".pdb");
65 | }
66 |
67 | ///
68 | /// Write a list of installer files.
69 | ///
70 | private static void LogFeatureFiles(string directory, string fileVersion)
71 | {
72 | var assemblies = Directory.GetFiles(directory, "*", SearchOption.AllDirectories);
73 | Console.WriteLine($"Installer files for version '{fileVersion}':");
74 |
75 | foreach (var assembly in assemblies.Where(FilterEntities))
76 | {
77 | Console.WriteLine($"'{assembly}'");
78 | }
79 | }
80 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Solution/build/Build.Changelog.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using Nuke.Common.Tools.Git;
3 | using Nuke.Common.Tools.GitHub;
4 |
5 | sealed partial class Build
6 | {
7 | ///
8 | /// Creates a Builder for creating a changelog for the current release.
9 | ///
10 | StringBuilder CreateChangelogBuilder()
11 | {
12 | Assert.True(File.Exists(ChangelogPath), $"Unable to locate the changelog file: {ChangelogPath}");
13 | Log.Information("Changelog: {Path}", ChangelogPath);
14 |
15 | var changelog = BuildChangelog();
16 | Assert.True(changelog.Length > 0, $"No version entry exists in the changelog: {ReleaseVersion}");
17 |
18 | return changelog;
19 | }
20 |
21 | ///
22 | /// Appends the GitHub compare URL to the changelog builder.
23 | ///
24 | void WriteGitHubCompareUrl(StringBuilder changelogBuilder)
25 | {
26 | var tags = GitTasks
27 | .Git("tag -l --sort=v:refname", logInvocation: false, logOutput: false)
28 | .ToArray();
29 |
30 | if (tags.Length < 2) return;
31 |
32 | if (changelogBuilder[^1] != '\r' || changelogBuilder[^1] != '\n') changelogBuilder.AppendLine(Environment.NewLine);
33 | changelogBuilder.Append("Full changelog: ");
34 | changelogBuilder.Append(GitRepository.GetGitHubCompareTagsUrl(tags[^1].Text, tags[^2].Text));
35 | }
36 |
37 | ///
38 | /// Builds the changelog content for the current release.
39 | ///
40 | StringBuilder BuildChangelog()
41 | {
42 | const string separator = "# ";
43 |
44 | var hasEntry = false;
45 | var changelog = new StringBuilder();
46 | foreach (var line in File.ReadLines(ChangelogPath))
47 | {
48 | if (hasEntry)
49 | {
50 | if (line.StartsWith(separator)) break;
51 |
52 | changelog.AppendLine(line);
53 | continue;
54 | }
55 |
56 | if (line.StartsWith(separator) && line.Contains(ReleaseVersion))
57 | {
58 | hasEntry = true;
59 | }
60 | }
61 |
62 | TrimEmptyLines(changelog);
63 | return changelog;
64 | }
65 |
66 | ///
67 | /// Trims empty lines from the changelog builder.
68 | ///
69 | static void TrimEmptyLines(StringBuilder builder)
70 | {
71 | if (builder.Length == 0) return;
72 |
73 | while (builder[^1] == '\r' || builder[^1] == '\n')
74 | {
75 | builder.Remove(builder.Length - 1, 1);
76 | }
77 |
78 | while (builder[0] == '\r' || builder[0] == '\n')
79 | {
80 | builder.Remove(0, 1);
81 | }
82 | }
83 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Solution/install/Installer.Generator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Text.RegularExpressions;
6 | using WixSharp;
7 |
8 | namespace Installer;
9 |
10 | public static class Generator
11 | {
12 | ///
13 | /// Generates Wix entities, features and directories for the installer.
14 | ///
15 | public static WixEntity[] GenerateWixEntities(IEnumerable args)
16 | {
17 | var versionRegex = new Regex(@"\d+");
18 | var versionStorages = new Dictionary>();
19 |
20 | var revitFeature = new Feature
21 | {
22 | Name = "Revit Add-in",
23 | Description = "Revit add-in installation files",
24 | Display = FeatureDisplay.expand
25 | };
26 |
27 | foreach (var directory in args)
28 | {
29 | var directoryInfo = new DirectoryInfo(directory);
30 | var fileVersion = versionRegex.Match(directoryInfo.Name).Value;
31 | var feature = new Feature
32 | {
33 | Name = fileVersion,
34 | Description = $"Install add-in for Revit {fileVersion}",
35 | ConfigurableDir = $"INSTALL{fileVersion}"
36 | };
37 |
38 | revitFeature.Add(feature);
39 |
40 | var files = new Files(feature, $@"{directory}\*.*", FilterEntities);
41 | if (versionStorages.TryGetValue(fileVersion, out var storage))
42 | {
43 | storage.Add(files);
44 | }
45 | else
46 | {
47 | versionStorages.Add(fileVersion, [files]);
48 | }
49 |
50 | LogFeatureFiles(directory, fileVersion);
51 | }
52 |
53 | return versionStorages
54 | .Select(storage => new Dir(new Id($"INSTALL{storage.Key}"), storage.Key, storage.Value.ToArray()))
55 | .Cast()
56 | .ToArray();
57 | }
58 |
59 | ///
60 | /// Filter installer files and exclude from output.
61 | ///
62 | private static bool FilterEntities(string file)
63 | {
64 | return !file.EndsWith(".pdb");
65 | }
66 |
67 | ///
68 | /// Write a list of installer files.
69 | ///
70 | private static void LogFeatureFiles(string directory, string fileVersion)
71 | {
72 | var assemblies = Directory.GetFiles(directory, "*", SearchOption.AllDirectories);
73 | Console.WriteLine($"Installer files for version '{fileVersion}':");
74 |
75 | foreach (var assembly in assemblies.Where(FilterEntities))
76 | {
77 | Console.WriteLine($"'{assembly}'");
78 | }
79 | }
80 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn/Config/Logging/LoggerConfiguration.cs:
--------------------------------------------------------------------------------
1 | #if (Container)
2 | using Microsoft.Extensions.DependencyInjection;
3 | #endif
4 | #if (Hosting)
5 | using Microsoft.Extensions.Logging;
6 | #endif
7 | using Serilog;
8 | using Serilog.Core;
9 | using Serilog.Events;
10 |
11 | namespace Nice3point.Revit.AddIn.Config.Logging;
12 |
13 | ///
14 | /// Application logging configuration
15 | ///
16 | ///
17 | ///
18 | #if (Container)
19 | /// public class Class(ILogger logger)
20 | /// {
21 | /// private void Execute()
22 | /// {
23 | /// logger.Information("Message");
24 | /// }
25 | /// }
26 | #elseif (Hosting)
27 | /// public class Class(ILogger<Class> logger)
28 | /// {
29 | /// private void Execute()
30 | /// {
31 | /// logger.LogInformation("Message");
32 | /// }
33 | /// }
34 | #endif
35 | ///
36 | ///
37 | public static class LoggerConfiguration
38 | {
39 | #if (Container)
40 | private const string LogTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}]: {Message:lj}{NewLine}{Exception}";
41 | #elseif (Hosting)
42 | private const string LogTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] {SourceContext}: {Message:lj}{NewLine}{Exception}";
43 | #endif
44 |
45 | #if (Container)
46 | public static void AddSerilogConfiguration(this IServiceCollection services)
47 | {
48 | var logger = CreateDefaultLogger();
49 | services.AddSingleton(logger);
50 |
51 | AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
52 | }
53 | #elseif (Hosting)
54 | public static void AddSerilogConfiguration(this ILoggingBuilder builder)
55 | {
56 | var logger = CreateDefaultLogger();
57 | builder.AddSerilog(logger);
58 |
59 | AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
60 | }
61 | #endif
62 |
63 | private static Logger CreateDefaultLogger()
64 | {
65 | return new Serilog.LoggerConfiguration()
66 | .WriteTo.Debug(LogEventLevel.Debug, LogTemplate)
67 | .MinimumLevel.Debug()
68 | .CreateLogger();
69 | }
70 |
71 | #if (Container)
72 | private static void OnUnhandledException(object sender, UnhandledExceptionEventArgs args)
73 | {
74 | var exception = (Exception)args.ExceptionObject;
75 | var logger = Host.GetService();
76 | logger.Fatal(exception, "Domain unhandled exception");
77 | }
78 | #elseif (Hosting)
79 | private static void OnUnhandledException(object sender, UnhandledExceptionEventArgs args)
80 | {
81 | var exception = (Exception)args.ExceptionObject;
82 | var logger = Host.GetService>();
83 | logger.LogCritical(exception, "Domain unhandled exception");
84 | }
85 | #endif
86 | }
--------------------------------------------------------------------------------
/source/Nice3point.Revit.AddIn.Application/Config/Logging/LoggerConfiguration.cs:
--------------------------------------------------------------------------------
1 | #if (Container)
2 | using Microsoft.Extensions.DependencyInjection;
3 | #endif
4 | #if (Hosting)
5 | using Microsoft.Extensions.Logging;
6 | #endif
7 | using Serilog;
8 | using Serilog.Core;
9 | using Serilog.Events;
10 |
11 | namespace Nice3point.Revit.AddIn.Config.Logging;
12 |
13 | ///
14 | /// Application logging configuration
15 | ///
16 | ///
17 | ///
18 | #if (Container)
19 | /// public class Class(ILogger logger)
20 | /// {
21 | /// private void Execute()
22 | /// {
23 | /// logger.Information("Message");
24 | /// }
25 | /// }
26 | #elseif (Hosting)
27 | /// public class Class(ILogger<Class> logger)
28 | /// {
29 | /// private void Execute()
30 | /// {
31 | /// logger.LogInformation("Message");
32 | /// }
33 | /// }
34 | #endif
35 | ///
36 | ///
37 | public static class LoggerConfiguration
38 | {
39 | #if (Container)
40 | private const string LogTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}]: {Message:lj}{NewLine}{Exception}";
41 | #elseif (Hosting)
42 | private const string LogTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] {SourceContext}: {Message:lj}{NewLine}{Exception}";
43 | #endif
44 |
45 | #if (Container)
46 | public static void AddSerilogConfiguration(this IServiceCollection services)
47 | {
48 | var logger = CreateDefaultLogger();
49 | services.AddSingleton(logger);
50 |
51 | AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
52 | }
53 | #elseif (Hosting)
54 | public static void AddSerilogConfiguration(this ILoggingBuilder builder)
55 | {
56 | var logger = CreateDefaultLogger();
57 | builder.AddSerilog(logger);
58 |
59 | AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
60 | }
61 | #endif
62 |
63 | private static Logger CreateDefaultLogger()
64 | {
65 | return new Serilog.LoggerConfiguration()
66 | .WriteTo.Debug(LogEventLevel.Debug, LogTemplate)
67 | .MinimumLevel.Debug()
68 | .CreateLogger();
69 | }
70 |
71 | #if (Container)
72 | private static void OnUnhandledException(object sender, UnhandledExceptionEventArgs args)
73 | {
74 | var exception = (Exception)args.ExceptionObject;
75 | var logger = Host.GetService();
76 | logger.Fatal(exception, "Domain unhandled exception");
77 | }
78 | #elseif (Hosting)
79 | private static void OnUnhandledException(object sender, UnhandledExceptionEventArgs args)
80 | {
81 | var exception = (Exception)args.ExceptionObject;
82 | var logger = Host.GetService>();
83 | logger.LogCritical(exception, "Domain unhandled exception");
84 | }
85 | #endif
86 | }
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/source/ModalModule/ModalModule.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | true
5 | latest
6 | x64
7 | true
8 | Debug R20;Debug R21;Debug R22;Debug R23;Debug R24;Debug R25
9 | $(Configurations);Release R20;Release R21;Release R22;Release R23;Release R24;Release R25
10 |
11 |
12 |
13 |
14 | 2020
15 | net48
16 |
17 |
18 | 2021
19 | net48
20 |
21 |
22 | 2022
23 | net48
24 |
25 |
26 | 2023
27 | net48
28 |
29 |
30 | 2024
31 | net48
32 |
33 |
34 | 2025
35 | net8.0-windows
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/samples/SingleProjectWpfModelessApplication/RevitAddIn/Views/RevitAddinView.xaml:
--------------------------------------------------------------------------------
1 |
15 |
18 |
19 |
20 |
21 |
23 |
24 |
25 |
26 |
28 |
29 |
30 |
32 |
38 |
42 |
48 |
53 |
54 |
55 |
56 |
57 |
58 |
63 |
69 |
75 |
76 |
83 |
84 |
--------------------------------------------------------------------------------
/samples/SingleProjectWpfModelessApplication/RevitAddIn/ViewModels/RevitAddinViewModel.cs:
--------------------------------------------------------------------------------
1 | using Autodesk.Revit.UI;
2 | using Autodesk.Revit.UI.Selection;
3 | using Nice3point.Revit.Toolkit.External.Handlers;
4 | using Nice3point.Revit.Toolkit.Options;
5 | using RevitAddIn.Utils;
6 | using RevitAddIn.Views;
7 |
8 | namespace RevitAddIn.ViewModels;
9 |
10 | public sealed partial class RevitAddInViewModel : ObservableObject
11 | {
12 | private readonly ActionEventHandler _externalHandler = new();
13 | private readonly AsyncEventHandler _asyncExternalHandler = new();
14 | private readonly AsyncEventHandler _asyncIdExternalHandler = new();
15 |
16 | [ObservableProperty] private string _element = string.Empty;
17 | [ObservableProperty] private string _category = string.Empty;
18 | [ObservableProperty] private string _status = string.Empty;
19 |
20 | [RelayCommand]
21 | private void ShowSummary()
22 | {
23 | _externalHandler.Raise(application =>
24 | {
25 | var selectionConfiguration = new SelectionConfiguration();
26 | var reference = application.ActiveUIDocument.Selection.PickObject(ObjectType.Element, selectionConfiguration.Filter);
27 | var element = reference.ElementId.ToElement(application.ActiveUIDocument.Document)!;
28 |
29 | Element = element.Name;
30 | Category = element.Category.Name;
31 | });
32 | }
33 |
34 | [RelayCommand]
35 | private async Task DeleteElementAsync()
36 | {
37 | var deletedId = await _asyncIdExternalHandler.RaiseAsync(application =>
38 | {
39 | var document = application.ActiveUIDocument.Document;
40 |
41 | var selectionConfiguration = new SelectionConfiguration();
42 | var reference = application.ActiveUIDocument.Selection.PickObject(ObjectType.Element, selectionConfiguration.Filter);
43 |
44 | var transaction = new Transaction(document);
45 | transaction.Start("Delete element");
46 | document.Delete(reference.ElementId);
47 | transaction.Commit();
48 |
49 | return reference.ElementId;
50 | });
51 |
52 | TaskDialog.Show("Deleted element", $"ID: {deletedId}");
53 | }
54 |
55 | [RelayCommand]
56 | private async Task SelectDelayedElementAsync()
57 | {
58 | Status = "Wait 2 second...";
59 | await Task.Delay(TimeSpan.FromSeconds(2));
60 |
61 | await _asyncExternalHandler.RaiseAsync(application =>
62 | {
63 | var selectionConfiguration = new SelectionConfiguration();
64 | WindowController.Hide();
65 |
66 | var reference = application.ActiveUIDocument.Selection.PickObject(ObjectType.Element, selectionConfiguration.Filter);
67 | var element = reference.ElementId.ToElement(application.ActiveUIDocument.Document)!;
68 | WindowController.Show();
69 |
70 | Element = element.Name;
71 | Category = element.Category.Name;
72 | });
73 |
74 | Status = string.Empty;
75 | }
76 | }
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/source/ModelessModule/Views/ModelessModuleView.xaml:
--------------------------------------------------------------------------------
1 |
15 |
18 |
19 |
20 |
21 |
23 |
24 |
25 |
26 |
28 |
29 |
30 |
32 |
38 |
42 |
48 |
53 |
54 |
55 |
56 |
57 |
58 |
63 |
69 |
75 |
76 |
83 |
84 |
--------------------------------------------------------------------------------
/samples/MultiProjectSolution/build/Build.CreateInstaller.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 | using Serilog.Events;
3 | using Nuke.Common.Tooling;
4 | using Nuke.Common.Utilities;
5 | using Nuke.Common.Tools.DotNet;
6 | using static Nuke.Common.Tools.DotNet.DotNetTasks;
7 |
8 | sealed partial class Build
9 | {
10 | ///
11 | /// Create the .msi installers.
12 | ///
13 | Target CreateInstaller => _ => _
14 | .DependsOn(Compile)
15 | .Executes(() =>
16 | {
17 | const string configuration = "Release";
18 | foreach (var (wixInstaller, wixTarget) in InstallersMap)
19 | {
20 | Log.Information("Project: {Name}", wixTarget.Name);
21 |
22 | DotNetBuild(settings => settings
23 | .SetProjectFile(wixInstaller)
24 | .SetConfiguration(configuration)
25 | .SetVersion(ReleaseVersionNumber)
26 | .SetVerbosity(DotNetVerbosity.minimal));
27 |
28 | var builderFile = Directory
29 | .EnumerateFiles(wixInstaller.Directory / "bin" / configuration, $"{wixInstaller.Name}.exe")
30 | .FirstOrDefault()
31 | .NotNull($"No installer builder was found for the project: {wixInstaller.Name}");
32 |
33 | var targetDirectories = Directory.GetDirectories(wixTarget.Directory, $"* {configuration} *", SearchOption.AllDirectories);
34 | Assert.NotEmpty(targetDirectories, "No content were found to create an installer");
35 |
36 | var arguments = targetDirectories.Select(path => path.DoubleQuoteIfNeeded()).JoinSpace();
37 | var process = ProcessTasks.StartProcess(builderFile, arguments, logInvocation: false, logger: InstallerLogger);
38 | process.AssertZeroExitCode();
39 | }
40 | });
41 |
42 | ///
43 | /// Logs the output of the installer process.
44 | ///
45 | [SuppressMessage("ReSharper", "TemplateIsNotCompileTimeConstantProblem")]
46 | void InstallerLogger(OutputType outputType, string output)
47 | {
48 | if (outputType == OutputType.Err)
49 | {
50 | Log.Error(output);
51 | return;
52 | }
53 |
54 | var arguments = ArgumentsRegex.Matches(output);
55 | var logLevel = arguments.Count switch
56 | {
57 | 0 => LogEventLevel.Debug,
58 | > 0 when output.Contains("error", StringComparison.OrdinalIgnoreCase) => LogEventLevel.Error,
59 | _ => LogEventLevel.Information
60 | };
61 |
62 | if (arguments.Count == 0)
63 | {
64 | Log.Write(logLevel, output);
65 | return;
66 | }
67 |
68 | var properties = arguments
69 | .Select(match => match.Value.Substring(1, match.Value.Length - 2))
70 | .Cast