Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Element Selection Changed Event - Implementation Struggles

19 REPLIES 19
SOLVED
Reply
Message 1 of 20
TheRealChrisHildebran
7162 Views, 19 Replies

Element Selection Changed Event - Implementation Struggles

TheRealChrisHildebran
Advocate
Advocate

I'm struggling with monitoring Revit for element selection changes. 

 

Window selections are no problem; monitoring element selection changes as a user "Control Picks" them is the main issue im working on a solution for. Way back Revit apparently had a "Element Selection Changed" Method but its been hidden/deprecated to the dismay of many in our community.

 

Because of this many in our community have come up with some great ideas to solve this seemingly rudimentary issue.

Specifically, detailed on Jeremy Tammicks awesome site The Building Coder, is this post which lays out the three most viable workarounds.

  1. Use the OnIdling event to check current selection
  2. Use a Timer to raise an event at a specified interval. 
  3. Use Revit's Modify Tab PropertyChanged Event to return a list of selected elements.

The one ive tried to implement is #3 which was originally suggested by a member of our community named Vilo here. Jeremy Tammick has made this code available for our use in the SDK Samples. Here is the repository of the current "working state" of my implementation.

 

Jeremy had great suggestions as usual but the issues below remain.

  1. The "PropertyChanged" event continues to fire after Unsubscribing to the event. 
  2. Element Ids are reported multiple times based on how many times the event is Subscribed/Un-Subscribed. See Screenshot #1 (Probably ties into item #1 Event still fires. Another thought i had was does the "PropertyChanged" get fired again because of a resulting PropertyChange  from the initial "PropertyChanged" event?
  3. Not all ElementIds are reported as they are selected. Hunch is that there is not property change at some point. Once a dissimilar Element is selected causing a property change the event fires and all of the Element Ids are shown.

If you've found a solution to the main problem of "Element Selection Changed Monitoring" or to the implementation of Vilo's suggestion to subscribe to the Modify Tabs property changed event i, and i suspect many other, would appreciate some feedback. 

 

PanelEvent Fire Example.png

 

 

Element Selection Changed Event - Implementation Struggles

I'm struggling with monitoring Revit for element selection changes. 

 

Window selections are no problem; monitoring element selection changes as a user "Control Picks" them is the main issue im working on a solution for. Way back Revit apparently had a "Element Selection Changed" Method but its been hidden/deprecated to the dismay of many in our community.

 

Because of this many in our community have come up with some great ideas to solve this seemingly rudimentary issue.

Specifically, detailed on Jeremy Tammicks awesome site The Building Coder, is this post which lays out the three most viable workarounds.

  1. Use the OnIdling event to check current selection
  2. Use a Timer to raise an event at a specified interval. 
  3. Use Revit's Modify Tab PropertyChanged Event to return a list of selected elements.

The one ive tried to implement is #3 which was originally suggested by a member of our community named Vilo here. Jeremy Tammick has made this code available for our use in the SDK Samples. Here is the repository of the current "working state" of my implementation.

 

Jeremy had great suggestions as usual but the issues below remain.

  1. The "PropertyChanged" event continues to fire after Unsubscribing to the event. 
  2. Element Ids are reported multiple times based on how many times the event is Subscribed/Un-Subscribed. See Screenshot #1 (Probably ties into item #1 Event still fires. Another thought i had was does the "PropertyChanged" get fired again because of a resulting PropertyChange  from the initial "PropertyChanged" event?
  3. Not all ElementIds are reported as they are selected. Hunch is that there is not property change at some point. Once a dissimilar Element is selected causing a property change the event fires and all of the Element Ids are shown.

If you've found a solution to the main problem of "Element Selection Changed Monitoring" or to the implementation of Vilo's suggestion to subscribe to the Modify Tabs property changed event i, and i suspect many other, would appreciate some feedback. 

 

PanelEvent Fire Example.png

 

 

19 REPLIES 19
Message 2 of 20

gopinathrbe
Participant
Participant

PropertyChanged event unsubscribing works only for public static methods

public static void TabPropertyChangedEvent(object sender, PropertyChangedEventArgs e)
{

PropertyChanged event unsubscribing works only for public static methods

public static void TabPropertyChangedEvent(object sender, PropertyChangedEventArgs e)
{

Message 3 of 20

FAIR59
Advisor
Advisor
Accepted solution

there is a 4th workaround.

Every time  the selection changes, a button has the option to check if it should be enabled via the  AvailabilityClassName property. The downside of this mechanisme is, that the button needs to visible. This can easily be accomplished by adding the button to the QuickAccessToolBar.

 

Define the button in the OnStartup method

public Autodesk.Revit.UI.Result OnStartup(UIControlledApplication application)
{
    application.CreateRibbonTab("FAIR");
    RibbonPanel m_ribbonPanel = application.CreateRibbonPanel("FAIR", "ModifyPanel");
    string thisAssemblyPath = Assembly.GetExecutingAssembly().Location;
    PushButtonData buttonData = new PushButtonData("cmd_Dummy",
               string.Format("X"), thisAssemblyPath, "FAIR_Space.cmd_Dummy");
    buttonData.AvailabilityClassName = "FAIR_Space.CommandEnabler";
    m_ribbonPanel.AddItem(buttonData);

    application.ControlledApplication.ApplicationInitialized+=ControlledApplication_ApplicationInitialized;
    return Result.Succeeded;
}

with the CommandExecute-method and AvailabilityClass

    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
public class cmd_Dummy : IExternalCommand
{
    public Autodesk.Revit.UI.Result Execute(ExternalCommandData revit,
     ref string message, ElementSet elements)
    {
        return Result.Succeeded;
    }
}
public class CommandEnabler : IExternalCommandAvailability
{
    public bool IsCommandAvailable(UIApplication uiApp, CategorySet catSet)
    {
        UIDocument uidoc = uiApp.ActiveUIDocument;
        if (uidoc == null) return false;

        Autodesk.Revit.UI.Selection.Selection sel = uidoc.Selection;
        // Raise the SelectionChangedEvent
        return false; // disable button
    }
}

In the ControlledApplication_ApplicationInitialized-method move the button to the QuickAccessToolBar.

       void ControlledApplication_ApplicationInitialized(object sender, Autodesk.Revit.DB.Events.ApplicationInitializedEventArgs e)
       {
           adWin.RibbonControl ribbon = adWin.ComponentManager.Ribbon;
           adWin.RibbonTab FAIRTab = null;
           adWin.RibbonPanel MyPanel = null;
           adWin.RibbonItem MyButton = null;
           // find MyPanel and MyButton
           foreach (var tab in ribbon.Tabs)
           {
               if (tab.Id == "FAIR")
               {
                   FAIRTab = tab;
                   foreach (var panel in tab.Panels)
                   {
                       if (panel.Source.Title == "ModifyPanel")
                       {
                           MyPanel = panel;
                           foreach (var item in panel.Source.Items)
                           {
                               if (item.Id == "CustomCtrl_%CustomCtrl_%FAIR%ModifyPanel%cmd_Dummy")
                               {
                                   MyButton = item;
                                   break;
                               }
                           }
                       }
                   }
                   break;
               }
           }
           if (MyPanel != null && MyButton != null && FAIRTab != null )
           {
               // find a "nice"position for the button
               int position = 0;
               foreach (var item in adWin.ComponentManager.QuickAccessToolBar.Items)
               {
                   if (string.IsNullOrWhiteSpace(item.Id)) continue;
                   position++;
                   if (item.Id == "ID_REVIT_FILE_PRINT") break;
               }
               // place button on QuickAccessToolBar
               if (position < adWin.ComponentManager.QuickAccessToolBar.Items.Count)
               {
                   adWin.ComponentManager.QuickAccessToolBar.InsertStandardItem(position, MyButton);
               }
               else adWin.ComponentManager.QuickAccessToolBar.AddStandardItem(MyButton);

               // remove button from MyPanel and hide tab if no panels 
               FAIRTab.Panels.Remove(MyPanel);
               if (FAIRTab.Panels.Count == 0) FAIRTab.IsVisible = false;
           }
       }

there is a 4th workaround.

Every time  the selection changes, a button has the option to check if it should be enabled via the  AvailabilityClassName property. The downside of this mechanisme is, that the button needs to visible. This can easily be accomplished by adding the button to the QuickAccessToolBar.

 

Define the button in the OnStartup method

public Autodesk.Revit.UI.Result OnStartup(UIControlledApplication application)
{
    application.CreateRibbonTab("FAIR");
    RibbonPanel m_ribbonPanel = application.CreateRibbonPanel("FAIR", "ModifyPanel");
    string thisAssemblyPath = Assembly.GetExecutingAssembly().Location;
    PushButtonData buttonData = new PushButtonData("cmd_Dummy",
               string.Format("X"), thisAssemblyPath, "FAIR_Space.cmd_Dummy");
    buttonData.AvailabilityClassName = "FAIR_Space.CommandEnabler";
    m_ribbonPanel.AddItem(buttonData);

    application.ControlledApplication.ApplicationInitialized+=ControlledApplication_ApplicationInitialized;
    return Result.Succeeded;
}

with the CommandExecute-method and AvailabilityClass

    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
public class cmd_Dummy : IExternalCommand
{
    public Autodesk.Revit.UI.Result Execute(ExternalCommandData revit,
     ref string message, ElementSet elements)
    {
        return Result.Succeeded;
    }
}
public class CommandEnabler : IExternalCommandAvailability
{
    public bool IsCommandAvailable(UIApplication uiApp, CategorySet catSet)
    {
        UIDocument uidoc = uiApp.ActiveUIDocument;
        if (uidoc == null) return false;

        Autodesk.Revit.UI.Selection.Selection sel = uidoc.Selection;
        // Raise the SelectionChangedEvent
        return false; // disable button
    }
}

In the ControlledApplication_ApplicationInitialized-method move the button to the QuickAccessToolBar.

       void ControlledApplication_ApplicationInitialized(object sender, Autodesk.Revit.DB.Events.ApplicationInitializedEventArgs e)
       {
           adWin.RibbonControl ribbon = adWin.ComponentManager.Ribbon;
           adWin.RibbonTab FAIRTab = null;
           adWin.RibbonPanel MyPanel = null;
           adWin.RibbonItem MyButton = null;
           // find MyPanel and MyButton
           foreach (var tab in ribbon.Tabs)
           {
               if (tab.Id == "FAIR")
               {
                   FAIRTab = tab;
                   foreach (var panel in tab.Panels)
                   {
                       if (panel.Source.Title == "ModifyPanel")
                       {
                           MyPanel = panel;
                           foreach (var item in panel.Source.Items)
                           {
                               if (item.Id == "CustomCtrl_%CustomCtrl_%FAIR%ModifyPanel%cmd_Dummy")
                               {
                                   MyButton = item;
                                   break;
                               }
                           }
                       }
                   }
                   break;
               }
           }
           if (MyPanel != null && MyButton != null && FAIRTab != null )
           {
               // find a "nice"position for the button
               int position = 0;
               foreach (var item in adWin.ComponentManager.QuickAccessToolBar.Items)
               {
                   if (string.IsNullOrWhiteSpace(item.Id)) continue;
                   position++;
                   if (item.Id == "ID_REVIT_FILE_PRINT") break;
               }
               // place button on QuickAccessToolBar
               if (position < adWin.ComponentManager.QuickAccessToolBar.Items.Count)
               {
                   adWin.ComponentManager.QuickAccessToolBar.InsertStandardItem(position, MyButton);
               }
               else adWin.ComponentManager.QuickAccessToolBar.AddStandardItem(MyButton);

               // remove button from MyPanel and hide tab if no panels 
               FAIRTab.Panels.Remove(MyPanel);
               if (FAIRTab.Panels.Count == 0) FAIRTab.IsVisible = false;
           }
       }
Message 4 of 20
jeremytammik
in reply to: FAIR59

jeremytammik
Autodesk
Autodesk

Wow! I wish I could allot more than one like for this. It deserves dozens, at least.

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Wow! I wish I could allot more than one like for this. It deserves dozens, at least.

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 5 of 20

TheRealChrisHildebran
Advocate
Advocate

Thank you for the input Gopinath! Illuminating! I will make adjustments and see if this solves one of the problems im having. 

 

Best wishes, 

Chris

0 Likes

Thank you for the input Gopinath! Illuminating! I will make adjustments and see if this solves one of the problems im having. 

 

Best wishes, 

Chris

Message 6 of 20

TheRealChrisHildebran
Advocate
Advocate

Frank, firstly I share Jeremy's sentiment! Your suggestion appears to not only mitigate the open issues I'm having but, more than that, it eliminates the need for an event entirely! Woohoo! Ill be implementing this as soon as i can and will report back.

 

Many thanks from Portland, Oregon

Chris

0 Likes

Frank, firstly I share Jeremy's sentiment! Your suggestion appears to not only mitigate the open issues I'm having but, more than that, it eliminates the need for an event entirely! Woohoo! Ill be implementing this as soon as i can and will report back.

 

Many thanks from Portland, Oregon

Chris

Message 7 of 20

Correction to my last post. "...eliminates the nedd for a time or property watcher entire.'

0 Likes

Correction to my last post. "...eliminates the nedd for a time or property watcher entire.'

Message 8 of 20

TheRealChrisHildebran
Advocate
Advocate

Elapsed times to report a count of selected elements for the three most viable workarounds are very close and, to me, completely acceptable. 

 

Though the simplest and most dependable is definitely FAIR59's contribution.

Otherwise i'd go with the OnIdling approach.

 

Thanks again Frank!

 

--------------------------------------------------------------------------
Selection Monitor - OnPropertyChanged

Element Id's: <hidden>
Count: 600
Elapsed Time: 0.0041 seconds

--------------------------------------------------------------------------
-------------------------------------------------------------------------- Selection Monitor - OnIdling Element Id's: <hidden> Count: 600 Elapsed Time: 0.0033 seconds --------------------------------------------------------------------------
-------------------------------------------------------------------------- Selection Monitor - Fair Availability Class Name Workaround Element Id's: <hidden> Count: 600 Elapsed Time: 0.0048 seconds --------------------------------------------------------------------------

 

0 Likes

Elapsed times to report a count of selected elements for the three most viable workarounds are very close and, to me, completely acceptable. 

 

Though the simplest and most dependable is definitely FAIR59's contribution.

Otherwise i'd go with the OnIdling approach.

 

Thanks again Frank!

 

--------------------------------------------------------------------------
Selection Monitor - OnPropertyChanged

Element Id's: <hidden>
Count: 600
Elapsed Time: 0.0041 seconds

--------------------------------------------------------------------------
-------------------------------------------------------------------------- Selection Monitor - OnIdling Element Id's: <hidden> Count: 600 Elapsed Time: 0.0033 seconds --------------------------------------------------------------------------
-------------------------------------------------------------------------- Selection Monitor - Fair Availability Class Name Workaround Element Id's: <hidden> Count: 600 Elapsed Time: 0.0048 seconds --------------------------------------------------------------------------

 

Message 9 of 20

jeremytammik
Autodesk
Autodesk

Thank you very much for testing and benchmarking and reporting the interesting results.

 

Could you share the add-in that you use to generate those?

 

I think this could potentially make a very illuminating and instructive blog post.

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes

Thank you very much for testing and benchmarking and reporting the interesting results.

 

Could you share the add-in that you use to generate those?

 

I think this could potentially make a very illuminating and instructive blog post.

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 10 of 20

TheRealChrisHildebran
Advocate
Advocate

Absolutely Jeremy. Ill post a link first thing in the morning (Portland Oregon USA time TUesday 1/14/2020 @ approx 9:00am).

0 Likes

Absolutely Jeremy. Ill post a link first thing in the morning (Portland Oregon USA time TUesday 1/14/2020 @ approx 9:00am).

Message 11 of 20

TheRealChrisHildebran
Advocate
Advocate

Jeremy, attached is a zip file of the solution containing three of the four workarounds for selection monitoring. The solution should open and compile right into the "C:\ProgramData\Autodesk\Revit\Addins\2020" directory.

0 Likes

Jeremy, attached is a zip file of the solution containing three of the four workarounds for selection monitoring. The solution should open and compile right into the "C:\ProgramData\Autodesk\Revit\Addins\2020" directory.

Message 12 of 20
Anonymous
in reply to: TheRealChrisHildebran

Anonymous
Not applicable

I am currently using workaround 1. OnIdling event ot the three, now four, identified so far, and am having a few issues and from the forums there is clearly a degree of unreliability with this approach and after all they are all workarounds. As others have said, wanting to know the current element selection is a common requirement for developers and 'a seemingly rudimentary issue'. If this is the case why do Autodesk and the Revit/Api/Sdk developpers make it so hard and why did they abandon the ElementSelectionChanged method. So many developers reinventing the wheel and each spending hours trying to figure  which is the least worst workaround for something that should be really simple along with the vague threat that if we come up with something too good or clever it might well be illegal ! It would really be helpful to understand a bit what their strategy and logic is or after all these years are they just too busy to implement a solution for this and enjoy watching us all battle with it ! Alternatively do they not want us to do this so make it really hard if so why not just tell us that or block it completely. Workaround 4 looks quite promising and interesting so I think I will go and spend a few hours on that now but really we shouldn't have to experiment like this.

I am currently using workaround 1. OnIdling event ot the three, now four, identified so far, and am having a few issues and from the forums there is clearly a degree of unreliability with this approach and after all they are all workarounds. As others have said, wanting to know the current element selection is a common requirement for developers and 'a seemingly rudimentary issue'. If this is the case why do Autodesk and the Revit/Api/Sdk developpers make it so hard and why did they abandon the ElementSelectionChanged method. So many developers reinventing the wheel and each spending hours trying to figure  which is the least worst workaround for something that should be really simple along with the vague threat that if we come up with something too good or clever it might well be illegal ! It would really be helpful to understand a bit what their strategy and logic is or after all these years are they just too busy to implement a solution for this and enjoy watching us all battle with it ! Alternatively do they not want us to do this so make it really hard if so why not just tell us that or block it completely. Workaround 4 looks quite promising and interesting so I think I will go and spend a few hours on that now but really we shouldn't have to experiment like this.

Message 13 of 20
pgibsonHVST5
in reply to: FAIR59

pgibsonHVST5
Contributor
Contributor

This is a really nice and elegant solution.  I am trying to implement this with a modeless window that will respond to user selection changes and it seems that I will have to have a singleton class that has the CommandEnabler logic to somehow then get to my view (window) and ViewModel (as the window.DataContext) in order to actually use the current selection information that is gathered.  Just wondering if you have taken this next step in some way that you are willing to discuss. 

0 Likes

This is a really nice and elegant solution.  I am trying to implement this with a modeless window that will respond to user selection changes and it seems that I will have to have a singleton class that has the CommandEnabler logic to somehow then get to my view (window) and ViewModel (as the window.DataContext) in order to actually use the current selection information that is gathered.  Just wondering if you have taken this next step in some way that you are willing to discuss. 

Message 14 of 20
Anonymous
in reply to: TheRealChrisHildebran

Anonymous
Not applicable

@TheRealChrisHildebran 

 

Can you test this selection monitor add-in also with your add-in ?

http://use-full.com/RevitAddin1.zip 

 

how does is work,

 

If the left mousebutton is clicked, or the esc is pressed, there is an event fired.

Because the mousebutton / escape fired before the selection is recognized these events start the idle event handler.

After the idle event is fired the selection is displayed in the userform and the idle handler is removed.

 

kind regards,

Ivo Lafeber

0 Likes

@TheRealChrisHildebran 

 

Can you test this selection monitor add-in also with your add-in ?

http://use-full.com/RevitAddin1.zip 

 

how does is work,

 

If the left mousebutton is clicked, or the esc is pressed, there is an event fired.

Because the mousebutton / escape fired before the selection is recognized these events start the idle event handler.

After the idle event is fired the selection is displayed in the userform and the idle handler is removed.

 

kind regards,

Ivo Lafeber

Message 15 of 20
mehdi.blanchard
in reply to: FAIR59

mehdi.blanchard
Enthusiast
Enthusiast

@FAIR59 This is awesome.

 

In my experience this workaround works a lot better than using the Modify tab for the following reasons :

  • When I was selecting an element from the same family type that was previously selected, I wasn't receiving a second event from the Modify Tab
  • You get the Revit context

 

0 Likes

@FAIR59 This is awesome.

 

In my experience this workaround works a lot better than using the Modify tab for the following reasons :

  • When I was selecting an element from the same family type that was previously selected, I wasn't receiving a second event from the Modify Tab
  • You get the Revit context

 

Message 16 of 20
Anonymous
in reply to: TheRealChrisHildebran

Anonymous
Not applicable

Which Using Assembly is adWin or RibbonTab, just can't find it?

 

Thx

0 Likes

Which Using Assembly is adWin or RibbonTab, just can't find it?

 

Thx

Message 17 of 20
TheRealChrisHildebran
in reply to: Anonymous

TheRealChrisHildebran
Advocate
Advocate

Its this one Josef "C:\Program Files\Autodesk\Revit 2021\AdWindows.dll"

 

Change the year for your needs. 

 

TheRealChrisHildebran_0-1618582483510.png

 

0 Likes

Its this one Josef "C:\Program Files\Autodesk\Revit 2021\AdWindows.dll"

 

Change the year for your needs. 

 

TheRealChrisHildebran_0-1618582483510.png

 

Message 18 of 20

matthew_conwayN7C2G
Enthusiast
Enthusiast

I've implemented this solution exactly as written above and it is working, but inconsistently. When I am hovering over drop-down buttons, the CommandEnabler is firing no problem, but when I select elements in the model space, it fires less consistently (at the beginning it fires well for selecting two or three elements, but the more I click, the less it fires consistently, and at some points I can click numerous different elements without it firing once). Does this have to do with the current visibility of @FAIR59 's quickaccess button being changed without my knowledge? I was using the "Modify" check command, but had the same issue @mehdi.blanchard was having of selecting the same family type.

0 Likes

I've implemented this solution exactly as written above and it is working, but inconsistently. When I am hovering over drop-down buttons, the CommandEnabler is firing no problem, but when I select elements in the model space, it fires less consistently (at the beginning it fires well for selecting two or three elements, but the more I click, the less it fires consistently, and at some points I can click numerous different elements without it firing once). Does this have to do with the current visibility of @FAIR59 's quickaccess button being changed without my knowledge? I was using the "Modify" check command, but had the same issue @mehdi.blanchard was having of selecting the same family type.

Message 19 of 20

jeremy_tammik
Autodesk
Autodesk

Check out the new SelectionChanged event and Revit SDK sample in Revit 2023:

  

Application: SelectionChanged
Revit Platform: All
Revit Version: 2023.0
First Released For: 2023.0
Programming Language: C#
Skill Level: Beginning
Category: Basics
Type: ExternalApplication
Subject: SelectionChanged event
Summary: The sample implements IExternalApplication interface and subscribes SelectionChanged event in OnStartUp; the registered event handler will dump selected references related information to log files.

    

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes

Check out the new SelectionChanged event and Revit SDK sample in Revit 2023:

  

Application: SelectionChanged
Revit Platform: All
Revit Version: 2023.0
First Released For: 2023.0
Programming Language: C#
Skill Level: Beginning
Category: Basics
Type: ExternalApplication
Subject: SelectionChanged event
Summary: The sample implements IExternalApplication interface and subscribes SelectionChanged event in OnStartUp; the registered event handler will dump selected references related information to log files.

    

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
Message 20 of 20

jeremy_tammik
Autodesk
Autodesk

Here is the Revit 2023 API functionality for this:

 

https://thebuildingcoder.typepad.com/blog/2022/04/whats-new-in-the-revit-2023-api.html#4.2.19

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open

Here is the Revit 2023 API functionality for this:

 

https://thebuildingcoder.typepad.com/blog/2022/04/whats-new-in-the-revit-2023-api.html#4.2.19

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report