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));
Solved! Go to Solution.
Solved by jeremytammik. Go to Solution.
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.
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?
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.
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.
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
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;
}
}
}
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