2

I am wanting to rewrite one of my Revit Add ins so that it utilizes WPF with MVVM because I like the look and functionality of WPF better than Windows Forms.

I have used the Revit Template Wizzard from Jeremy Tammik for the Form based add in, but adding a WPF user control seems not to work (a run time error that the xaml resource cannot be found).

I found a WPF MVVM revit add in example (AddMaterials, here is the github link, which will add materials from an Excel spreadsheet) but it does not follow what I am expecting to see at the top level.

  • Revit Add ins have an app.cs file which tells Revit how to register and access the DLL (ribbon panel buttons etc).
  • A windows WPF app will have app.xaml as the top level entry point.
  • The Add Materials project has neither which tells me that it must be a class library, however the views are not using UserControls rather they are Windows which I prefer. However Visual Studio does not let you add a Window for a Class Library type project.

The third issue is easily solved by simply copying windows from a WPF application project into a class library project. But I don't really understand how the class library will instantiate in Revit without following the app.cs code from the template. Is anyone else creating add-ins this way, and if so can you let me in on any tricks or discussions that will help? Has anyone created a WPF Revit addin template for Visual Studio?

When I add a WPF window and try to instantiate it I get an error that it cannot find the xaml resource (System.IO.IOException: Cannot locate resource 'xxxx.xaml'). I have tried to fix this according to advice found when googling for this error, but to no avail. I am thinking it comes from being in a form based project, and that I may have to just start with a new project without the form stuff.

I have now verified that indeed you can start with the Revit AddIn Wizzard and use WPF . . . I started from scratch and copied in a window created in another project and got it to run (after adding the various references, namespaces, etc). So my problem seems to just be with the original project which already had a bunch of form stuff added.

Paul Gibson
  • 622
  • 1
  • 9
  • 23

1 Answers1

5

Yes, I'm using WPF to create Revit Addins. It works well. You can easily create your own WPF template from the SDK samples:

  1. Start with one of the Autodesk-provided SDK samples. I used the "DockableDialogs" sample. I know this one works, your mileage may vary with the others. If you're looking for windows rather than docked panes in the UI, another sample (perhaps the AddMaterials sample) is probably simpler.
  2. I used Visual Studio to turn the sample into a template. File - Export Template -> select "DockableDialogs" or other WPF sample project.
  3. Create a new project based on the template you just created. This was the easiest method I could find to get the WPF internal bits wired up correctly.

I'm not specifically familiar with the AddMaterials project, but to clarify your bullet points.

  1. Revit Addins - It's not the file name (app.cs) but rather they must extend IExternalApplication or IExternalCommand. If you are creating a xaml interface (rather than just running a command from a ribbon button) you'll use 'IExternalApplication' as your entry point. Look for something like this in the sample:

    public class ThisApplication : IExternalApplication ...
    
  2. I don't used a top level app.xaml, but instead have page.xaml pages which are called by the Revit app. In my case these are Pages rather than Windows, which extend the IDockablePaneProvider class. These must be registered with the application which can then can be show, hide, etc your Panes. I imagine this is simpler with Windows, but haven't done it myself. For the dockable panes, your xaml.cs should start out something like:

      public partial class MainPage : Page, Autodesk.Revit.UI.IDockablePaneProvider ...
    
  3. Yes, the project is a class library in the sense that it is a collection of classes, at least one of which extends IExternalApplication or IExternalCommand. Remember that you're not creating a standalone application, but adding functionality to an existing Windows application (Revit). Revit will instantiate the ThisApplication class and then call its .OnStartup() method when the Revit application starts. This shouldn't stop you from adding .xaml or .cs files to the project, though. I can do it using VS Community 2015 using Ctrl-Shift-A.

Hopefully this gets you started - I've been able to implement a WPF UI in Revit without any prior WPF experience, and I'm not even a real programmer, so it's definitely possible. Good Luck!

addendum

If you want to add WPF elements to an existing revit addin, you can follow the instructions here: How can I connect xaml and xaml.cs files

Ultimately I found it easier to migrate my addin code into a template made from a working sample, you may want to try this approach as well.

Community
  • 1
  • 1
0w3n
  • 325
  • 1
  • 9
  • Thank you for the cogent reply. I understand your points, and find them helpful especially in how to frame my questions. In terms of Revit the IExternalApplication class is where you can have your add in registered with a ribbon panel button . . . do your WPF add ins have this? I ask because Add Materials does not, and even when I add it the code seems to be ignored (it uses the OnStartup even handler to accomplish this). – Paul Gibson Oct 20 '16 at 17:34
  • @PaulGibson AddMaterials uses a single Command : IExternalCommand, this command then calls var window = new MaterialsView { DataContext = browser }; to create the window. This command is loaded from the .addin file. If you use an IExternalApplication (as I do) then this can add commands through OnStartup. If you look at the .addin for AddMaterials it has this line: AddMaterials.Command. If you add an IExternalApplication named, for example, "newApp" you'll add newNamespace.newApp . – 0w3n Oct 20 '16 at 17:56
  • Doh! I have looked at that so many times but did not catch that! – Paul Gibson Oct 20 '16 at 18:03
  • But still no joy with the xaml not found (from original question and expanded in edit). – Paul Gibson Oct 20 '16 at 18:36
  • About point 2: ever tried MVVM approach on those pages ? can't get a delegate command to work ... and using WPF with event handlers is something i'd largely want to avoid – L.Trabacchin Apr 20 '17 at 18:11