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: 

IUpdater, simple example needed

7 REPLIES 7
SOLVED
Reply
Message 1 of 8
aclarke
2604 Views, 7 Replies

IUpdater, simple example needed

I don't understand where to place the following code.  Reading the comments, the author points to the OnStartup() but I am not sure where 'element' in the element.get_Paramter(BuiltInParameter...) is coming from.

 

Where does this last bit of code go?  LINK

 

Thanks for any assistance.

 

 

var parameter = element.get_Parameter(BuiltInParameter.ROOM_AREA);
UpdaterRegistry.AddTrigger(_updater.GetUpdaterId(), doc, 
    new List<ElementId>() { new ElementId(197280)}, 
    Element.GetChangeTypeParameter(parameter));

 

 

 

7 REPLIES 7
Message 2 of 8
jeremytammik
in reply to: aclarke

The first place to go to for simple Revit API samples is the Revit SDK.

  

That is its one and only purpose.

   

One of the samples is DynamicModelUpdate: Dynamic Model Update used to maintain relative position between elements; Move a section marker to maintain relative position with a window.

 

Please install and explore the Revit SDK samples.

 



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

Message 3 of 8
aclarke
in reply to: jeremytammik

Thank you,  my first search in the SDK, I did a window explorer search for "Updater" and the only CS file was for a Structural example with some monster code.

 

I notice for all Updater examples use the designation is 'm_'   does the m_ have a meaning?  or just indicates Updater variables?

Message 4 of 8
jeremytammik
in reply to: aclarke

The `m_` prefix is a convention used in C++ to mark member variables.

   

It is not used in C#.

   

Therefore, you can tell that (possibly, probably?) whoever implemented the C# code has little experience in C#. and more experience in C++.

   

To tell the truth, I did the same thing when I started with C#.

  

By the way, you should almost always ask the Internet such things before bothering other people with it.

  

Look what an Internet search says right out of the box:

  

https://duckduckgo.com/?q=m_+prefix

  

https://stackoverflow.com/questions/13018189/what-does-m-variable-prefix-mean

  

Not that I mind, but it is more efficient for you yourself. 

  

I ask the Internet dozens of things like that every single day, and I would never get anything else done at all if I asked all my questions in discussion forums.

   



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

Message 5 of 8
aclarke
in reply to: jeremytammik

Hi Jeremy,

A Forum to me is like a fishing pond, you drop in a line (by asking a question) anchor your pole, while you walk the bank with a second pole looking for the fish (an answer).  You answered my question while I researched other items.  Time well spent.

 

I'm sorry you feel my question is bothersome to others, this makes me feel hesitant to ask questions not knowing what questions are except-able. 

 

anyway, thank you very much for your help.

 

 

 

Message 6 of 8
jeremytammik
in reply to: aclarke

Dear Alan,

  

Thank you for your appreciation and for picking up and clarifying that.

 

I totally agree with the approach you describe and might do exactly the same myself in that situation.

 

You question did not bother me at all.

 

There are some questions that do bother me, where the answer is more obvious, or easily searchable and findable, and I get the impression no effort at all was made before asking.

  

I don't want anybody to be too hesitant asking, and I do wish everybody would perform conduct some minimal research beforehand, always.

  

Best regards,

  

Jeremy

  



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

Message 7 of 8
aclarke
in reply to: jeremytammik

Hi Jeremy, I just want to share my solution, with help from a friend.  I hope this is simple enough of an example and helpful for others.  This is an IExternalCommand example.

 

 

using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System;
using System.Collections.Generic;
using System.Linq;

namespace _Updater
{

    class Updater01 : IUpdater
    {
        // ----------------------------------------------------------------------------------------
        // | Updater Id |
        // ----------------------------------------------------------------------------------------
        private const string Id = "B7FA01EA-F749-473F-AD7A-4A35A44802B3";

        // ----------------------------------------------------------------------------------------
        // | Constructor |
        // ----------------------------------------------------------------------------------------
        public UpdaterId updater { get; set; }
        public Updater01(Document doc, AddInId addInId)
        {
            updater = new UpdaterId(addInId, new Guid(Id));
            RegisterUpdater(doc);
            RegisterTriggers();
        }

        // ----------------------------------------------------------------------------------------
        // | Register Updater |
        // ----------------------------------------------------------------------------------------
        public void RegisterUpdater(Document doc)
        {
            if (UpdaterRegistry.IsUpdaterRegistered(this.updater, doc))
            {
                UpdaterRegistry.RemoveAllTriggers(this.updater);
                UpdaterRegistry.UnregisterUpdater(this.updater, doc);
            }

            UpdaterRegistry.RegisterUpdater(this, doc);
        }

        // ----------------------------------------------------------------------------------------
        // | Register Trigger | <-- Contains Element Filter
        // ----------------------------------------------------------------------------------------
        public void RegisterTriggers()
        {
            if (this.updater != null && UpdaterRegistry.IsUpdaterRegistered(this.updater))
            {
                UpdaterRegistry.RemoveAllTriggers(this.updater);
                UpdaterRegistry.AddTrigger(this.updater,
                    new ElementCategoryFilter(BuiltInCategory.OST_Walls), Element.GetChangeTypeAny());
            }

        }

        // ----------------------------------------------------------------------------------------
        // | Execute Method | <-- Stuff to do
        // ----------------------------------------------------------------------------------------
        public void Execute(UpdaterData data)
        {
            Document doc = data.GetDocument();

            List<ElementId> elementIds = data.GetModifiedElementIds().ToList();
            foreach (ElementId id in elementIds)
            {
                Element e = doc.GetElement(id);
                TaskDialog.Show("td", e.Name);
            }
        }

        // ----------------------------------------------------------------------------------------
        // | Updater Members | <-- Extra members
        // ----------------------------------------------------------------------------------------
        public string GetAdditionalInformation()
        {
            return "NA";
        }

        public ChangePriority GetChangePriority()
        {
            return ChangePriority.MEPFixtures;
        }

        public UpdaterId GetUpdaterId()
        {
            return updater;
        }

        public string GetUpdaterName()
        {
            return "Updater01";
        }
    }
}

 

 

 

using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;

namespace _Updater
{
    [Transaction(TransactionMode.Manual)]
    [Regeneration(RegenerationOption.Manual)]
    class Command : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            Document doc = commandData.Application.ActiveUIDocument.Document;
            AddInId activeId = commandData.Application.ActiveAddInId;

            Updater01 updater01 = new Updater01(doc, activeId);

            return Result.Succeeded;
        }
    }
}

 

 

Message 8 of 8
jeremytammik
in reply to: aclarke

Thank you for sharing this nice simple DMU sample.

 

I integrated it into The Building Coder samples release 2021.0.150.10:

 

https://github.com/jeremytammik/the_building_coder_samples/releases/tag/2021.0.150.10

 

Here is the diff to the previous release:

 

https://github.com/jeremytammik/the_building_coder_samples/compare/2021.0.150.9...2021.0.150.10

 

In doing so, I noticed that already include a nice simple DMU sample in the module CmdElevationWatcher that reacts to elevation view creation and compares using the DocumentChanged event versus DMU to track that happening

 

https://thebuildingcoder.typepad.com/blog/2012/06/documentchanged-versus-dynamic-model-updater.html

 

Here is my slightly modified version of your code:

 

  [Transaction( TransactionMode.Manual )]
  class CmdSimpleUpdaterExample : IExternalCommand
  {
    class SimpleUpdater : IUpdater
    {
      const string Id = "d42d28af-d2cd-4f07-8873-e7cfb61903d8";

      UpdaterId _updater_id { get; set; }

      public SimpleUpdater( 
        Document doc, 
        AddInId addInId )
      {
        _updater_id = new UpdaterId( 
          addInId, new Guid( Id ) );

        RegisterUpdater( doc );
        RegisterTriggers();
      }

      public void RegisterUpdater( Document doc )
      {
        if( UpdaterRegistry.IsUpdaterRegistered( 
          _updater_id, doc ) )
        {
          UpdaterRegistry.RemoveAllTriggers( _updater_id );
          UpdaterRegistry.UnregisterUpdater( _updater_id, doc );
        }
        UpdaterRegistry.RegisterUpdater( this, doc );
      }

      public void RegisterTriggers()
      {
        if( null != _updater_id 
          && UpdaterRegistry.IsUpdaterRegistered( 
            _updater_id ) )
        {
          UpdaterRegistry.RemoveAllTriggers( _updater_id );
          UpdaterRegistry.AddTrigger( _updater_id,
            new ElementCategoryFilter( BuiltInCategory.OST_Walls ), 
            Element.GetChangeTypeAny() );
        }
      }

      public void Execute( UpdaterData data )
      {
        Document doc = data.GetDocument();

        ICollection<ElementId> ids 
          = data.GetModifiedElementIds();

        IEnumerable<string> names 
          = ids.Select<ElementId, string>( 
            id => doc.GetElement( id ).Name );

        TaskDialog.Show( "Simple Updater", 
          string.Join<string>( ",", names ) );
      }

      public string GetAdditionalInformation()
      {
        return "NA";
      }

      public ChangePriority GetChangePriority()
      {
        return ChangePriority.MEPFixtures;
      }

      public UpdaterId GetUpdaterId()
      {
        return _updater_id;
      }

      public string GetUpdaterName()
      {
        return "SimpleUpdater";
      }
    }

    public Result Execute( 
      ExternalCommandData commandData, 
      ref string message,
      ElementSet elements )
    {
      UIApplication uiapp = commandData.Application;
      Document doc = uiapp.ActiveUIDocument.Document;
      AddInId addInId = uiapp.ActiveAddInId;

      SimpleUpdater su = new SimpleUpdater( doc, addInId );

      return Result.Succeeded;
    }
  }

 

Best regards,

 

Jeremy

 



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

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

Post to forums  

Autodesk DevCon in Munich May 28-29th


Rail Community