Git Product home page Git Product logo

revit.dependencyinjection.templates's Introduction

Revit Dependency Injection Templates

This repository contains a project template for use with Revit Dependency Injection with Unity.

The project templates are available on Nuget

Installation

  1. Install the latest .Net SDK
  2. Run dotnet new -i Revit.DependencyInjection.Templates to install the project templates

Usage

Just run dotnet new in a required folder. dotnet new RevitDiUnity --name ProjectName

Template

For dependency Injection refer to Revit Dependency Injection with Unity repo or Unity Documentation.

The template contains sample IExternalApplication Class wrapped in RevitApp

UI Creation

The following method is used to register Tabs, Panels & Buttons

// This attribute is crucial and should have a unique GUID (created by template by default)
[ContainerProvider("{{GUID}}")]
public class App : RevitApp
{
	public override void OnCreateRibbon(IRibbonManager ribbonManager)
	{
		var br = ribbonManager.GetLineBreak();

		var sampleTab = ribbonManager.CreateTab("TabName");
		var samplePanel = ribbonManager.CreatePanel(sampleTab.GetTabName(), "PanelName");

		samplePanel.AddPushButton<ButtonClass, ButtonAvailability>($"Button{br}Name", "Image");
	}
	[...]
}
samplePanel.AddPushButton<ButtonClass, ButtonAvailability>($"Button{br}Name", "image");

ButtonClass is a class implementing RevitAppCommand<App> where <App> is a name of the application class

ButtonAvailability is class implementing IExternalCommandAvailability

Image is a name of image file used for button icon. You should create two files for each button. One 32x32px & one 16x16px. Place them somewhere in Resources folder. Remember to follow the convention for naming the files "Image32" & "Image16".

Container Registration

public class App : RevitApp
{
	[...]
	public override Result OnStartup(IUnityContainer container, UIControlledApplication application)
	{
		// Register Your services here
		container.RegisterType<ISampleService, SampleService>();
		// Or use Extension Methods
		container.RegisterSampleServies();

		// This registers Revit Async Handler (ref. below)
		container.AddRevitAsync(GetAsyncSettings);
	}
	[...]
}

RevitAsync

Registering RevitAsync container.AddRevitAsync(GetAsyncSettings); you will register an instance of IRevitEventHandler that will allow you to execute methods within Revit Context. As the rest of the functions here it's been created by the guys at the excellent Onbox Framework

You can inject it into any registered class by

public class SampleClass
{
	private readonly IRevitEventHandler _eventHandler;

	public SampleClass(IRevitEventHandler eventHandler)
	{
		_eventHandler = eventHandler;
	}
}

Then You can run it by

// With return value
public async Task<T> GetSomethingFromRevit
{
	var returnValue = await _eventHandler.RunAsync(uiApp =>
	{
		// Access Revit Application Classes as such
		var doc = uiApp.ActiveUIDocument.Document;

		return something;
	});
}

// As void
public async Task DoSomethingInRevit
{
	await _eventHandler.RunAsync(uiApp =>
	{
		// Access Revit Application Classes as such
		var doc = uiApp.ActiveUIDocument.Document;
		
		// Your Logic Here
	}
}

If you prefer different implementation you could use the very popular Revit.Async, Register an instance of RevitTask where required, Create Your own implementation of IExternalEventHandler or any other.

Commands

Commands should inherit from RevitAppCommand<App> where <App> is the name of the application class.

//Remember to decorate the class with the Transaction Attribute
[Transaction(TransactionMode.Manual)]
public class SampleWindowCommand : RevitAppCommand<App>
{
	public override Result Execute(IUnityContainer container, ExternalCommandData commandData, ref string message, ElementSet elements)
	{
		// Your Logic Here
	}
}

WPF Views

The template uses Prism.Core library to handle MVVM implementation. You can follow Prism or any other MVVM convention.

Create a standard XAML Window & a ViewModel

in Window class inject ViewModel class

public partial class SampleWindow : Window
{
	public SampleWindowViewModel ViewModel { get; }

	public SampleWindow(SampleWindowViewModel viewModel)
	{
		ViewModel = viewModel;
		InitializeComponent();
	}
}

In XAML you can set data context as such DataContext="{Binding RelativeSource={RelativeSource Self}, Path=ViewModel}"

Then register both View & ViewModel as transient

container.RegisterType<SampleWindow>();
container.RegisterType<SampleWindowViewModel>();

Opening a windows is as simple as

var window = container.Resolve<SampleWindow>();
window.Show();

ViewModel

By Default Prism View Model should inherit from BindableBase Inject any Dependencies You may need

public class SampleWindowViewModel : BindableBase
{
	private readonly ISampleService _sampleService;
	
	public SampleWindowViewModel(ISampleService sampleService)
	{
		_sampleService = sampleService;
	}

Properties

Properties have SetProperty from BindableBase implementing INotifyPropertyChanged

// Example Collection property to be bound
private ObservableCollection<Element> _elements;

public ObservableCollection<Element> Elements
{
	get => _elements;
	set => SetProperty(ref _elements, value);
}

// Remember to Instantiate the collection!
public SampleWindowViewModel(ISampleService sampleService)
{
	[...]
	Elements = new ObservableCollection<Element>();
}

// Example Element property to be bound
private Element _selectedElement;

public Element SelectedElement
{
	get => _selectedElement;
	set => SetProperty(ref _selectedElement, value);
}

You can bind them as such

<ListView ItemsSource="{Binding Elements}"
          SelectedItem="{Binding SelectedElement}">
	<ListView.ItemTemplate>
		<DataTemplate>
			// You can access properties of a bound class in following way
			<TextBlock Text="{Binding Name, Mode=OneWay}"/>
			// When Binding to Revit Api Classes remember set One Way Binding as they cannot be set outside of Revit Context
		</DataTemplate>
	</ListView.ItemTemplate>
</ListView>

Commands

Delegate Commands are Prism Standard for ICommand implementation

// Create Delegate Command and define Function
public DelegateCommand DoSomethingCommand { get; set; }
private async void DoSomething()
{
	// Your Logic
}

public SampleWindowViewModel(ISampleService sampleService)
{
	[...]
	// Register Command
	DoSomethingCommand = new DelegateCommand(DoSomething);
}

Binding Commands

<Button Command="{Binding DoSomethingCommand}" />

For more advanced documentation refer to https://prismlibrary.com/docs/ or Brian Lagunas Pluralsight course that goes way beyond the scope here.

revit.dependencyinjection.templates's People

Contributors

coolicky avatar

Stargazers

 avatar  avatar

Watchers

 avatar

Forkers

mummyeye

revit.dependencyinjection.templates's Issues

FileNotFoundException

I always get a FileNotFoundException if i try to use the Revit.DependencyInjection.Unity package.
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.